今天遇到一个诡异的问题,之前在4.4.4手机上正常运行的动态加载在6.0.1上居然报找不到类,记录一下定位过程。
一开始觉得可能是dalvik和art中DexClassLoader的实现不一样,结果看了一下,逻辑一致。
于是想到把优化后的结果反编译看一下,dalvik可以使用baksmali将odex转为dex,art可以使用dextra从oat中抽取dex。
oat抽取出两个dex,都没有我的类:
开始有点怀疑dextra的准确性,为了验证一下,直接看一下apk里面的dex是否有我的类,结果让我吃了一惊,也是两个dex(这么小的包不该分包啊):
看了下两个dex,也是没有我的代码,但能和上面对应起来,那就是说dextra没问题。
那我的代码去哪了?
看到apk里面多了一个instant-run.zip,解压一看,全是dex,我的代码在这里面:
于是搜了一下instant-run,和这篇文章,算是找到了问题:
原来在Android studio编译安装的时候,判断了手机的版本,如果是4.4.4,则没有使用instant-run,动态加载没有问题。而使用6.0.1手机后,就编译成含有instant-run.zip的apk了。
instant-run 只在编译debug版本时起作用,原理也是利用动态加载机制,更新代码不用重新安装apk,只需要更新instant-run.zip,即可快速生效。
找到问题,直接禁用掉instant-run即可:
BTW: Google经常把新功能默认开启,让我们不知不觉就成了小白鼠。