前言
日常实际开发桥接包时,需要实现网络请求数据、页面判断跳转,并且实现网页加载URL、JS注入以及实现跨域功能。
这些功能代码量少,逻辑类似,因此容易导致代码重复度过高。并且这一块代码逻辑简单,反编译后容易阅读,从而造成安全性问题。
所以,我们尝试把逻辑代码迁移到C层实现,从而实现逻辑稳定性与安全性。
核心流程介绍
下面按照时间顺序介绍一下具体的流程:
1、原生层-Application
实现InstallReferrerClient,获取当前APP的渠道安装来源,并将安装来源的字符串写入SharedPreference文件。
SharedPreference文件使用默认的,也就是:包名_preferences.xml
注意key值,Demo中使用的是"install",根据项目修改。
2、原生层-MainActivity
定义并调用native重的init函数,实现AB面页面跳转。
优先初始化Shared Preference,如果担心存在并发时间差,Activity可以延迟3S进行native初始化以及调用。
函数名需要修改。
3、C++层 Java_com_test_MainActivity_init方法
与第2步一致,函数名需要进行同步修改。
该函数进行网络请求,根据返回值判断逻辑页面:例如:
1-直接进入A面主Activity;
3-直接进入B面主Activity;
2-则读取第1步获取到的渠道来源并写入的key,再判断是进入A面还是B面。
注意:下面的Activity的类名都要修改为自己包里的类名。
4、 原生层 B面WebViewActivity类启动
类中需要定义一个webview,并定义两个native函数;
由于webviewactivity页面初始化了webview,暴露了出来,需要实现一个回调函数,目前无法在C层实现,可能存在风险。(后续优化)
回调方法如下:
另外还有一个问题,js的注入必须在UI线程,所以尽管我们在C++层实现了js注入,但是还 得在java层单独处理,具体如下:
5.、C++层 Java_com_test_ioi_JNIWebActivity_init方法
完成B面主Activity的WebView动态创建和内容加载。
创建WebView,设置相关参数并实现相关逻辑,重点需要看的是载入URL。
因为有一个功能:如果首次进入B面,需要保存B面的URL,再次进入将直接使用已保存的B面URL。
上面实现了简单的加密方式进行保存B面URL,通过数字对换,字母大小写对换实现。
因为是对换,所以加解密通过同一个函数进行实现,具体明文和密文对比:
"https://m.705.games?code=9424533" ====》"sggkh://n.294.tznvh?xlwv=0575466"
接下来要调用java层的addJavascriptInterface方法设置一个接口类。
这个类必须先在Java层定义和实现,主要完成B面H5的回调和AF/AD的数据上包功能。
其具体定义和实现和之前java方案是一样的。
目前Demo中这部分的代码和之前一样,后面正式集成时,可尝试将其方法转换为native
6、C++层 Java_com_test_ioi_JNIWebActivity_getinfo方法
当WebView载入完内容后,需要回调当前函数完成js的注入。
同步修改
1、直接copy demo的 C++部分,也就是JNI目录。
2、直接copy demo的 build.gradle的部分。要特别注意红框中的部分:
3、修改C++的代码
1、首先需要访问的URL和SharedPreference的key
这里的可以要同步修改java层APP类中的相关方法。
2、其次是so库的名字。
这里要同时修改CMakeList.txt 和Java层对该so库的调用。
3、然后是native方法的名字。
整个方案总共定义了3个native方法,分别是:
Java_com_test_MainActivity_init
Java_com_test_ioi_JNIWebActivity_init
Java_com_test_ioi_JNIWebActivity_getinfo
4、修改Java的代码
1、主Activity
新增一个native方法,实现A/B面跳转。
2、B面主Activity
新增两个native方法,并调用webview.setWebViewClient。
3、主App类
调用InstallReferrerClient,记录信息到preference文件中。
4、JavascriptInterface的工具类
后面会尽量将它的内容也放到JNI层实现。