--摘自《Android进阶解密》
1.Instant Run编译部署
1)Hot swap:代码的增量改变不需要重启App,甚至不需要重启当前的Activity。修改一个现有方法中的代码时会采用Hot Swap
2)Warm Swap:App不需要重启,但是Activity需要重启。修改或删除一个现有的资源文件时会采用Warm Swap
3)Cold Swap:App需要重启,但是不需要重新安装。采用Cold Swap的情况很多,比如添加、删除或修改一个字段和方法、添加一个类等
2.Instant Run中的资源热修复可以简单地总结为两个步骤
1)创建新的AssetManager,通过反射调用addAssetPath方法加载外部的资源,这样新创建的AssetManager就含有了外部资源
2)将AssetManager类型的mAssets字段的引用全部替换为新创建的AssetManager
3.LoadNativeLibrary函数的流程图
1)判断so是否被加载过,两次ClassLoader是否是同一个,避免so重复加载
2)打开so并得到so句柄,如果so句柄获取失败,就返回false。创建新的SharedLibrary,如果传入path对应的library为空指针,就将新创建的SharedLibrary赋值给library,并将library存储到libraries_中
3)查找JNI_OnLoad的函数指针,根据不同情况设置was_successful的值,最终返回该was_successful中
4.so修复主要有两个方案
1)将so补丁插入到NativeLibraryElement数组的前部,让so补丁的路径先被返回和加载
2)调用System的load方法来接管so的加载入口
5.代码修复主要有3种方案:底层替换方案、类加载方案和Instant Run方案
1)类加载方案
QQ空间的超级补丁和Nuwa是将补丁包放在Element数组的第一个元素得到优先加载
微信Tinker将新旧APK做了diff,得到patch.dex,再将patch.dex与手机中APK的clsses.dex做合并,生成新的classes.dex,然后再运行时通过反射将classes.dex放在Element数组的第一个元素
饿了么的Amigo则是将补丁包中每个dex对应的Element取出来,之后组成新的Element数组,在运行时通过反射用新的Element数组替换掉现有的Element数组
2)底层替换方案
AndFix采用的是替换ArtMethod结构体中的字段,这样会有兼容问题,因为厂商可能会修改ArtMethod结构体,导致方法替换失败
Sophix采用的是替换整个ArtMethod结构体,这样不会存在兼容问题
欢迎关注我的微信公众号:安卓圈