这两天在demo上接入Tinker,对代码修复、资源修复、So库修复、签名、棒棒加固等流程和效果做验证;完成后、这些都测试通过,再进行与现用的nuwa做对比;所以、下面的内容就是两者功能及性能的对比分析
先看表、暂时不看阿里系的
|
Tinker |
NuWa |
|
|
dex修复 |
冷启动修复 |
冷启动修复 |
|
资源更新 |
yes |
no |
|
so替换 |
yes |
no |
|
性能损耗 |
较小 |
较大 |
|
补丁包大小 |
较小 |
较大 |
|
复杂度 |
较低 |
较低 |
|
占Rom体积 |
较大 |
较小 |
|
支持加固(梆梆) |
支持 |
支持 |
Nuwa的修复过程:
Gradle 的Nuwa plugin 作为一个customTask插入dexTask 任务链条之前,dexTask之前的task会把所有类都编译成字节码class,然后作为dexTask的输入;插入这个位置就能确保我们在生成dex 之前拿到所有的class,以便分析所有class然后生成补丁dex,这个过程称作hook
1、对所有类插桩:通过修改字节码, 为每一个编译好的class插入一个无参的构造函数, 然后让这个构造函数引用一个单独的dex中的类(这个类没有任何意义,只是为了跨dex引用)
2、收集变动过的类打成dex包:在customTask里会给每个参与编译的类文件生成hash, 第二次执行这个任务时对比每个类的hash值,如果不一样就认为是修改过的,将这些类收集到文件夹,然后调用buildtools里的工具生成dex.
修复补丁:loadPatch(String path). 负责将传入的补丁加载到内存,当启动应用时,Apk内的dex文件会被挨个通过ClassLoader加载到内存, 同时dex会按顺序维持一个列表,当程序需要加载一个类时,就去这个列表里查,一但查到就会使用对应dex具体的类,如果都没找到就会报ClassNotFound错误, 我们加载补丁的原理就是通过反射将我们的补丁dex插入到列表的最开始,这样当需要加载bug类时就会先在补丁dex里面找到,这样系统就会使用修复过的类,便达到了热修复的目的。
性能问题: Dalvik 平台存在插桩导致的性能损 耗,Art平台由于地址偏移 问题导致补丁包可能 过大的问题
Tinker修复过程:
在nuwa基础上进行优化,在合成时使用单独进程、Dalvik平台全量合成(解决了插 桩带来的性能损耗)、Art平台差量合成(解决了全量合成补丁体积过大),自研的DexDiff算法进行合成;解决了Dalvik平台性能 损耗问题、也解决了Art平台补丁包过大问题
问题:补丁包体 积过大(可接受)
Tinker的已知问题
· Tinker不支持修改AndroidManifest.xml,Tinker不支持新增四大组件(1.9.0支持新增非export的Activity);
· 由于Google Play的开发者条款限制,不建议在GP渠道动态更新代码;
· 在Android N上,补丁对应用启动时间有轻微的影响;
· 不支持部分三星android-21机型,加载补丁时会主动抛出"TinkerRuntimeException:checkDexInstallfailed";
· 对于资源替换,不支持修改remoteView。例如transition动画,notification icon以及桌面图标