javassist是一个原生的java应用,要让其在android中运行,需要进行一些修改。
1. 以android项目的形式引入javassist代码,并将代码中出错的地方直接注释。(对,直接注释即可,因为出错的基本都与我们将要使用的无关,如awt等)
2. 添加dx.jar的引用,用于生成dex的,我用了sdk中的23.0.3版本
3. 修改javassist/bytecode/ClassFile.java中的父类的方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15private void initSuperclass(String classname,String superclass) {
if (superclass != null) {
this.superClass = constPool.addClassInfo(superclass);
cachedSuperclass = superclass;
}
else if("java.lang.Object".equals(classname)){
//针对java.lang.Object作修改,否则会无限递归
this.superClass=0;
cachedSuperclass=null;
}
else {
this.superClass = constPool.addClassInfo("java.lang.Object");
cachedSuperclass = "java.lang.Object";
}
}
默认是没有针对java.lang.Object的判断的,如果没有则在加载android中的类时,java.lang.Object也会被默认以为是继承java.lang.Object,导致死循环
根源如下,如果superClass为空,则会默认给一个java.lang.Object的superClass。
1 | private void initSuperclass(String superclass) { |
4. 修改/javassist/bytecode/Descriptor.java
这个类用于生成类中的描述符,如参数的类型转为全路径形式之类的,但其默认都是针对CtClass,需要添加对普通Class的支持(查看代码)
5. 修改/javassist/ClassPool.java用于添加适合android的创建pool的接口
6. 修改/javassist/ClassPoolTail.java,针对dex创建一个类查找的方法
7. /javassist/CtClassType.java,修改类文件字节流读取为适合 android(dex) 的方式(原来为直接读取inputStream的形式)
8. 增加android的类查找、打dex的操作(代码目录:javassist/android/**)
因为javassist查找类需要使用实现ClassPath的对象对找,javassist只是针对java做的,所以需要针对android新增一种查找方法,主要实现三个方法 :1
2
3
4
5
6
7
8//获取类的成员域
List<FieldInfo> getClassFields(String classname, ConstPool cp);
//获取类的方法域
List<MethodInfo> getClassMethods(String classname, ConstPool cp);
//获取整个类对象(就是怎么读取到这个类的字节码)
ClassFile getClassFile(String classname) throws NotFoundException;
详情可以参看 javasssit