DroidFix

Project Url: bunnyblue/DroidFix
Introduction: AndroidHotFix/Android 代码热修复
More: Author   ReportBugs   OfficialWebsite   
Tags:
热修复-动态加载-动态部署-

Join the chat at https://gitter.im/bunnyblue/DroidFix

MoreInfo

详细原理

解决方案 该方案基于的是 android dex 分包方案的,关于 dex 分包方案,网上有几篇解释了,所以这里就不再赘述,具体可以看这里

   一个 ClassLoader 可以包含多个 dex 文件,每个 dex 文件是一个 Element,多个 dex 文件排列成一个有序的数组 dexElements,当找类的时候,会按顺序遍历 dex 文件,然后从当前遍历的 dex 文件中找类,如果找类则返回,如果找不到从下一个 dex 文件继续查找。    

所以为了实现补丁方案,所以必须从这些方法中入手,防止类被打上 CLASS_ISPREVERIFIED 标志。 最终空间的方案是往所有类的构造函数里面插入了一段代码,代码如下:

if (ClassVerifier.PREVENT_VERIFY) {
    System.out.println(AntilazyLoad.class);
}

其中 AntilazyLoad 类会被打包成单独的 antilazy.dex,这样当安装 apk 的时候,classes.dex 内的类都会引用一个在不相同 dex 中的 AntilazyLoad 类,这样就防止了类被打上 CLASS_ISPREVERIFIED 的标志了,只要没被打上这个标志的类都可以进行打补丁操作。 然后在应用启动的时候加载进来.AntilazyLoad 类所在的 dex 包必须被先加载进来,不然 AntilazyLoad 类会被标记为不存在,即使后续加载了 hack.dex 包,那么他也是不存在的,这样屏幕就会出现茫茫多的类 AntilazyLoad 找不到的 log。 所以 Application 作为应用的入口不能插入这段代码。(因为载入 hack.dex 的代码是在 Application 中 onCreate 中执行的,如果在 Application 的构造函数里面插入了这段代码,那么就是在 hack.dex 加载之前就使用该类,该类一次找不到,会被永远的打上找不到的标志)

How

  1 正式包会生成一份缓存文件,里面记录了所有 class 文件的 md5,还有一份 mapping 混淆文件。
  2. 在后续的版本中使用-applymapping 选项,应用正式版本的 mapping 文件,然后计算编译完成后的 class 文件的 md5 和正式版本进行比较,把不相同的 class 文件打包成补丁包。

  首先脚本开启 proguard
  然后运行 assembleDebug 或者 release
  然后修改代码 运行 assembleDebugDroidFix 稍等会在 app 的 DroidPatch 产生 apk 补丁

Android Support

Android version Status
Android 6.0 tested
Android 5.0 tested
Android < 5.0 tested
Apps
About Me
Google+: Trinea trinea
GitHub: Trinea