主包承担着修复的任务,是不能有bug的
当要进行修复的时候,
修改代码后,进行clean,然后在文件中的bin里面找到新编译成功的class文件,然后在这个目录中调出命令行,用dx -help 看提示 然后dx --dex --output=文件存放的地址\classes2.dex 文件的包名的所在的地址 。这样将生成的class文件编译成dex文件。
可以通过反编译进行验证:在存放的新生成的dex文件夹中,通过命令行 dex2jar classes2.dex 然后通过jd-gui进行反编译。
dex包是通过类加载器进行替换dexclassLoader ,如果要进行加载的话需要pathList,它存放的是类存放的地方。如果有多个dex的话,就能将多个进行加载。这样就找到了多个dex文件,通过dexElements 将各个的dex文件加载到集合中。但是dexclassLoader进行加载的时候是根据顺序进行加载的,先找到classes.dex如果找不到就找classes2.dex.
有个方法,就是在修复的时候进行替换,但是替换的时候需要将这个dex文件中所有的类都要进行替换,但这样比较麻烦,还有更加简单的方法。
我们进行使用的是插入的操作,就是将新的dex文件放在dexElements的前面来,让它首先被加载,那么在后面加载相同的名称的dex文件就不受影响。也就是将pathList dexElements中进行拼接,并且拼接在前面。
进行修复的类,要将下载的dex文件弄到缓存里面,避免被清除,因此要在缓存中进行创建文件夹。并且把所有的文件加载过来。然后调用补丁包的类加载器,然后找到系统的类加载器,然后进行合并combineArray,也就是将新生成的dex文件拼接到系统的加载器的列表中。
系统的classLoader PathClassLoader
pathList
dexElements
classes.dex
classes2.dex
补丁包的classsLoader DexClassLoader
pathList
dexElements
新的 classes2.dex
这样拼接过来的集合就是3个dex文件
调用修复的方法,如果有dex文件,就进行注入
这时候已经将内存卡中的dex复制到内存中了,因此删除了内存卡中了。这时候如果在缓存中没有了文件,那么就进行下载。
这里进行加载dex文件的加载,先查找需要修复的dex文件,然后再找到原有的dex文件,进行合并。这样就会让修复好的dex文件首先被加载,而相同的class只会被加载一次。
demo :https://github.com/yunzheyue/fixTest