在我的Android项目中,我尝试使用Transform API和Javasist来制作AOP框架。
但是有些类被转换为空类,然后我得到了构建错误:
/build/intermediates/transforms/jarMerging/debug/jars/1/1f/combined.jar] (Can't process class xxx/xxx/xxx/ABC.class
因为ABC.class在javasist句柄后变空(我只是用javasiit加载它然后回写)。
我写的修改类的代码是:
public void weave(String path) {
println("Begin to weave androidClassPath = " + androidClassPath)
println("Begin to weave path = " + path)
pool.appendClassPath(path)
pool.appendClassPath(androidClassPath)
pool.importPackage("android.util.Log");
File dir = new File(path)
int indexOfPackage = path.length() + 1;
if (dir.isDirectory()) {
dir.eachFileRecurse { File file ->
String filePath = file.absolutePath
if (isWeavableClass(filePath)) {
println("Begin to inject filePath " + filePath)
int end = filePath.length() - 6 // .class = 6
String className = filePath.substring(indexOfPackage, end).replace(File.separator, '.')
CtClass clazz = pool.getCtClass(className)
if (clazz.isFrozen()) {
clazz.defrost()
}
boolean timeDebugClass = false;
boolean parameterDebugClass = false;
if(clazz.hasAnnotation(TimingDebug.class)) {
timeDebugClass = true;
}
if(clazz.hasAnnotation(ParameterDebug.class)) {
parameterDebugClass = true;
}
println "timeDebugClass = "+ timeDebugClass + " parameterDebugClass = " + parameterDebugClass
CtMethod[] methods = clazz.getDeclaredMethods();
for (CtMethod method : methods) {
boolean emptyMethod = method.isEmpty()
boolean isNativeMethod = Modifier.isNative(method.getModifiers());
println("method name = " + method + " emptyMethod " + emptyMethod + " isNativeMethod = " + isNativeMethod)
if (!emptyMethod && !isNativeMethod) {
if (method.hasAnnotation(ParameterDebug.class) || parameterDebugClass) {
weaveParameterDebugMethod(clazz, method)
}
if (method.hasAnnotation(TimingDebug.class) || timeDebugClass) {
weaveTimingDebugMethod(clazz, method)
}
}
}
CtConstructor[] constructors = clazz.getDeclaredConstructors();
for(CtConstructor constructor: constructors){
boolean emptyMethod = constructor.isEmpty()
println("constructor name = " + constructor + " emptyMethod " + emptyMethod)
if (!emptyMethod) {
if (constructor.hasAnnotation(ParameterDebug.class) || parameterDebugClass) {
weaveParameterDebugMethod(clazz, constructor)
}
if (constructor.hasAnnotation(TimingDebug.class) || timeDebugClass) {
weaveTimingDebugMethod(clazz, constructor)
}
}
}
clazz.writeFile(path)
clazz.detach()
}
}
}
}