Tinker比对Nuwa

606 阅读3分钟
原文链接: mp.weixin.qq.com

这两天在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以及桌面图标