最近,在研究Android的dex加载相关的源码,想在DexClassLoader、BaseDexClassLoader、ClassLoader加点日志。但是日志又不能直接加,得通过dexPath限制一下,否则系统起不来,因为ClassLoader会被频繁调用。
BaseDexClassLoader
源码目录:libcore/dalvik/src/main/java/dalvik/system
编译目录:libcore
basedex.jpg
ClassLoader
源码目录:libcore/libdvm/src/main/java/java/lang
编译目录:libcore
classloader.jpg
编译
image.png我想着,是不是BaseDexClassLoader和ClassLoader不能同时修改,我先把BaseDexClassLoader保持不修改(使用原来的不带dexPath的super方法),编译一次之后,再修改。结果还是如此。
是不是由于构造方法的特殊性导致编译不通过呢?我尝试着在ClassLoader里新增个方法,BaseDexClassLoader仍然一样无法调用。
所以,上面的问题的本质归结为:同一目录下,两个Java类A和B,假如B增加个方法,A引用B的这个方法,编译不通过,报A找不到B的这个方法。
百度了半天也没有任何的资料说明相关的问题,只有自己一点点试探了。
模拟最简单的场景
https://www.jianshu.com/p/8b77c62273c0,这里正常生成Jar包。可见是libcore的特定环境导致了编译失败。
问题终于解决
搞了好几天,终于明白了,看编译日志是编译core-libart.jar包,是art!!!
而ClassLoader有两个类:
我只改了libdvm下的ClassLoader,而现在编译的是core-libart.jar,所以把两个目录下的ClassLoader都改一下就好了。
但是,发现安装app的时候,安装不上去,报错:
I/dalvikvm( 2564): java.lang.NullPointerException:
I/dalvikvm( 2564): at java.util.logging.Logger.log(Logger.java:1036)
I/dalvikvm( 2564): at java.util.logging.Logger$1.publish(Logger.java:81)
I/dalvikvm( 2564): at java.util.logging.Logger.log(Logger.java:924)
I/dalvikvm( 2564): at java.util.logging.Logger.warning(Logger.java:853)
I/dalvikvm( 2564): at dalvik.system.DexFile.log(DexFile.java:93)
I/dalvikvm( 2564): at dalvik.system.DexFile.openDexFile(DexFile.java:315)
I/dalvikvm( 2564): at dalvik.system.DexFile.<init>(DexFile.java:82)
I/dalvikvm( 2564): at dalvik.system.DexFile.<init>(DexFile.java:61)
I/dalvikvm( 2564): at dalvik.system.DexPathList.loadDexFile(DexPathList.java:263)
在ClassLoader里引用Logger打日志,就会报上面的错误。所以把Logger里加个null判断。
log.jpg
网友评论