重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
深入探索Android热修复技术原理这本书主要讲解了Android的热修复中的热部署,冷部署以及资源和so库的修复技巧。全文主要讲Sophix应对以上四个方面的技术解析,不管是自家产品还是业界其他方案的横纵对比,Sophix技术目前都是最优的。
创新互联公司专注为客户提供全方位的互联网综合服务,包含不限于做网站、成都做网站、阳朔网络推广、重庆小程序开发公司、阳朔网络营销、阳朔企业策划、阳朔品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联公司为所有大学生创业者提供阳朔建站搭建服务,24小时服务热线:18982081108,官方网址:www.cdcxhl.com
在事件分发流中,通过Hook钩子在事件传送到终点前截获并监控事件的传输,从而处理一些特定干预事件。
Sophix同时使用了热启动的底层替换方案及冷启动的类加载方案,两个方案使用的补丁是相同的。优先热启动。
基本参考InstantRun的实现:构造一个包含所有新资源的新的AssetManager。并在所有之前引用到原来的AssetManager通过反射替换掉。
Sophix不修改AssetManager的引用,构造的补丁包中只包含有新增或有修改变动的资源,在原AssetManager中addAssetPath这个包就可以了。资源包不需要在运行时合成完整包。
本质是对native方法的修复和替换。类似类修复反射注入方式,将补丁so库的路径插入到nativeLibraryDirectories数据最前面。
因为对手机伤害大。android手机热修复不能百分百用户修复成功,手机影响极大而且手机很容易出现bug,所以手机厂商不允许热修复。
注意:在5.0之前会有这个问题,5.0之后没有了
我们进行插桩的时机,便是上图中javac之后,dx之前。 另外,任何一个Task,都有input元素和output元素,以及可以设置doFirst闭包,表示执行任务之前先执行一段逻辑,设置doLast,表示执行任务执行之后再执行一段逻辑。
我们的思路是 在java变成class之后,在class变成 dex之前,将class进行ASM插桩。所以,我们要找的 gradle task 是 : transformClassesWithDexBuilderForRelease 或者 transformClassesWithDexBuilderForDebug 给它重写doFirst。 也可以 找到 gradle task : compileReleaseJavaWithJavac 或者 compileDebugJavaWithJavac. 给它重写 doLast。效果相同。
jar文件的插桩:
本文是在Android8.1.0上进行的源码分析,首先明确几个classloader的定义。
dexFile相当于一个classes.dex,而每一个dexFile也是一个Element,热修复的补丁包一定要插到classes.dex中的最前面的一个dex开始查找,因为dexFile是从classes.dex classes2.dex依次向后进行查找的.前面如果找到就不会找后面的类了。
反射工具类:
热修复:
成功使用:
最近研究了一下腾讯的热更新框架,以及一位大神开源的热更新后台服务框架,下边总结一下,希望对想了解的人有所帮助
tinker链接:
开源的热更新后台服务框架:
一、Tinker使用介绍:
官方文档好久没更新了,看起来费事,这里简单总结下怎么使用。
1、导入Sample工程
将官方给出的 Sample工程 在AndroidStudio中打开.首先一点,在app的build.gradle文件中找到tinkerId = getTinkerIdValue()并将其替换成tinkerId = "tinkerId",其中后面的值可以随意设置.再替换ignoreWarning = false为ignoreWarning = true.
2、编译运行原版apk
按照往常操作一样,编译打包debug apk并安装.此时Tinker会在工程的app/build/bakApk/目录下保存打包好的apk文件,找到刚才生成的apk文件,复制其完整文件名,在app的build.gradle文件找到tinkerOldApkPath这一项设置,并将其设置为tinkerOldApkPath = "${bakPath}/刚才生成的apk文件名"
3、修改源码 生成新版apk 补丁
在项目里随便改点内容,然后生成debug版的patch(补丁)apk文件。如图:
4、生成补丁包的位置如图:
只需将此补丁包放在MainActivity里边指定的加载补丁包的路径即可。
点击LOAD_PACH 加载执行修复,点击shouInfo 会显示PATCH is loaded,说明成功,然后点击KILL SELF 再次进入 就修复了。
到此为止tinker修复就成功了。然后说说怎么接入 tinker-manager 手机端的,以便跟热更新后台的修复做对接。
步骤参考文档链接: 按照此文档接入就行,我在这里对参数进行一下说明
下边两参数做测试的话为空即可
针对Android平台,Dexposed支持函数级别的在线热更新,例如对已经发布在应用市场上的宿主APK,当我们从crash统计平台上发现某个函数调用有bug,导致经常性crash,这时,可以在本地开发一个补丁APK,并发布到服务器中,宿主APK下载这个补丁APK并集成后,就可以很容易修复这个crash。
Dexposed是基于久负盛名的开源Xposed框架实现的一个Android平台上功能强大的无侵入式运行时AOP框架。
Dexposed的AOP实现是完全非侵入式的,没有使用任何注解处理器,编织器或者字节码重写器。集成Dexposed框架很简单,只需要在应用初始化阶段加载一个很小的JNI库就可以,这个加载操作已经封装在DexposedBridge函数库里面的canDexposed函数中,源码如下所示:
/**
* Check device if can run dexposed, and load libs auto.
*/
public synchronized static boolean canDexposed(Context context) {
if (!DeviceCheck.isDeviceSupport(context)) {
return false;
}
//load xposed lib for hook.
return loadDexposedLib(context);
}
private static boolean loadDexposedLib(Context context) {
// load xposed lib for hook.
try {
if (android.os.Build.VERSION.SDK_INT 19){
System.loadLibrary("dexposed_l");
} else if (android.os.Build.VERSION.SDK_INT == 10
|| android.os.Build.VERSION.SDK_INT == 9 ||
android.os.Build.VERSION.SDK_INT 14){
System.loadLibrary("dexposed");
}
return true;
} catch (Throwable e) {
return false;
}
}
Dexposed实现的hooking,不仅可以hook应用中的自定义函数,也可以hook应用中调用的Android框架的函数。Android开发者将从这一点得到很多好处,因为我们严重依赖于Android SDK的版本碎片化。