FengMap楼层地图源码分析隐藏logo

2023-11-09 20:51

本文主要是介绍FengMap楼层地图源码分析隐藏logo,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在使用第三方Android SDK产品中,大多SDK都有logo,如百度地图,高德地图,然而,这些SDK在嵌入项目使用过程中会发现,手机屏幕就那么大点,logo遮住了冰山一角,就非常影响UI的美观,于是,大多工程师都会看源码去找一些SDK里面的设计漏洞去隐藏Logo,

如:百度地图隐藏logo:https://blog.csdn.net/zhangphil/article/details/47953695

蜂鸟的FengMap楼层地图也不例外,下面是通过源码分析去隐藏FengMa楼层地图的logo,第三方SDK在使用logo时,基本都有两种方式:

第一种:直接绘制渲染上去,但是这种与界面合为一体的,在调整时很不方便,很少使用。

第二种:使用图片水印的形式去添加到view中,这种方式就简单了许多,且可以摆放在界面的任何位置。

蜂鸟的FengMap楼层地图使用的正好是第二种,放在屏幕的右下角,百度地图也是使用第二种添加形式...

这些资源在下载SDK时,都会放在SDK打好的jar包里面,SDK里面也包含JNI的一些.so库,.so库里面是C的代码,方便java通过JNI来快速调用渲染UI,同时达到SDK适配不同的手机CPU架构的目的,这些都是不可以改动的! 使用过程中直接去调用jar包里面的资源即可,以jar包的形式去添加引入,图片marker和一些控制图标也放在jar里面的assets目录下,如fengmap的目录和水印logo:

 

分析完jar包和.so库里面的基本资源后,就可以直接去分析源码,达到我们隐藏logo的目的。看上面assets目录下watermarker.png就是FengMap的logo了,那么,在使用中,怎么去找这张logo引入的入口呢?也就是加载这张图片到view中了。

FengMap和百度地图有些类似,找入口当然要找能在layout里面加载渲染的view了,然而FengMap入口View是通过FMMapView加载的,但是在FMMapView中并没有找到引入watermarker这张logo图片的方法,只是引入加载了一些动画资源。

 

之后通过代码执行去FMMapView.getViewCount()时,里面只有根布局RelativeLayout,也没有找到类似ImageView或ImageButton能加载logo图片之类的view,也没多余的其他view添加到RelativeLayout里面,这样就可以证明logo不是在FMMapView里面add的。

那么继续往上分析,FMMapView里面没有找到,找初始化完FMMapView继而获取FMMap这个操作地图的控制类,能过源码查看,只是看到加载了assets目录下的楼层地图和主题,通过反射去获取图层的操作而已,也没有找到加载watermarker.png logo的地方,但是找到了渲染的接口了。

 

如加载默认主题资源:

加载图层控件指北针图标:

但是找到了一个关键的词和方法:getRender()(获取渲染),并且返回一个FMGLRenderer渲染对象

通过返回的FMGLRenderer类去继续往上深探,发现FMGLRenderer继承自FMMapRenderer类,实现了Renderer接口,

Renderer接口是GLSurfaceView里面的接口,GLSurfaceView是一个渲染类,这样就有了渲染的源头。是系统里面自带类,无法在里面操作渲染,只能由其他类继承或实现接口代理渲染,那么这条线索走不通,看继承类。

那么再来看看继承的FMGLRenderer类,刚好在FMGLRenderer里面看到了添加watermarker.png logo的水印图标。

但是是通过JniView去添加的。那么看看JniView里面有些什么。JniView里面都是封装的.so库里面的方法,通过java调用去渲染

当调用JniView.addWaterMarker(this.viewHandle, "pic/watermarker.png")添加完成后,调用混淆过的方法this.d() ,d方法里面都是设置logo在屏幕中的位置和尺寸。

到此,在JniView里面找到了操作logo的方法,

包括:

addWaterMarker(添加图标),

getWaterMartSize(获取图标大小),

setWaterMartPosition(设置图标位置),

hiddenWaterMartPosition(隐藏图标)

 

方法找到了,但是是以Jni的形式去调用的,那么问题就来了,怎么使用JniView里面提供的java调用Jni的方法?

这就得回到FMGLRenderer里面去看怎么调用这些方法了:

从调用的方法传参可以看出,每交调用操作logo方法时,都必须传入一个参数叫viewHolder的参数,这个参数是一个long值,是通过初始化时创建获取上下文的hashCode值做标识的,哈希值是什么呢:我觉得百度百科回答比较确切一些:

public int hashCode()返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行hashcode比较时所用的信息没有被修改。

 

到这里,方法找到了,方法的参数也明确了,只需要调用JniView.hiddenWaterMartPosition(viewHandle),确保viewHandle的哈希值一致就ok了,在FMMap里面,除了获取渲染入口时提供的渲染类,还封装且返回viewhandle的值,所以可以直接通过FMMap.getViewHandle返回hashcode值,切都是同一个对象,没有被改变过,hashCode完全相同。

还有一点要注意的就是,FengMap地图有加载流程操作,加载调回流程:

地图设置加载回调监听--->回调地图加载成功

设置主题监听---->回调主题加载成功

在渲染地图时,地图加载成功后回调时去设置隐藏logo是隐藏不了的,

只能等主题加载成功后调回方法里面去设置隐藏logo才生效。

 

原因:

1.地图加载和地图主题加载是分开的,需要分别设置监听。

2.先渲染主题再添加logo,这样logo才能显示,如果先渲染logo,再渲染主题,那么logo就会被覆盖

最后展示隐藏右下角logo后的地图

在FengMap地图SDK版本2.1.3之前可用 , 2.1.3之后的版本升级后去掉了隐藏Logo的方法,得重新寻找其他方式隐藏Logo!

 

 

 

 

 

这篇关于FengMap楼层地图源码分析隐藏logo的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/378384

相关文章

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

Java字符串操作技巧之语法、示例与应用场景分析

《Java字符串操作技巧之语法、示例与应用场景分析》在Java算法题和日常开发中,字符串处理是必备的核心技能,本文全面梳理Java中字符串的常用操作语法,结合代码示例、应用场景和避坑指南,可快速掌握字... 目录引言1. 基础操作1.1 创建字符串1.2 获取长度1.3 访问字符2. 字符串处理2.1 子字

Python 迭代器和生成器概念及场景分析

《Python迭代器和生成器概念及场景分析》yield是Python中实现惰性计算和协程的核心工具,结合send()、throw()、close()等方法,能够构建高效、灵活的数据流和控制流模型,这... 目录迭代器的介绍自定义迭代器省略的迭代器生产器的介绍yield的普通用法yield的高级用法yidle

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

Python实现无痛修改第三方库源码的方法详解

《Python实现无痛修改第三方库源码的方法详解》很多时候,我们下载的第三方库是不会有需求不满足的情况,但也有极少的情况,第三方库没有兼顾到需求,本文将介绍几个修改源码的操作,大家可以根据需求进行选择... 目录需求不符合模拟示例 1. 修改源文件2. 继承修改3. 猴子补丁4. 追踪局部变量需求不符合很

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3