复制代码
public class ThreadRunVisitor extends ClassVisitor {
private String className;
private boolean needInject;
public ThreadRunVisitor(String className, ClassVisitor classVisitor) {
super(Opcodes.ASM5, classVisitor);
this.className = className;
}
@Override
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
//判断是否需要给该类的方法注入
this.needInject = isInjectClass(className, interfaces, superName);
super.visit(version, access, name, signature, superName, interfaces);
}
@Override
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
MethodVisitor methodVisitor = this.cv.visitMethod(access, name, descriptor, signature, exceptions);
boolean isInject = this.needInject && isInjectMethod(name, descriptor);
if (!isInject) {
return methodVisitor;
}
return (MethodVisitor) new AdviceAdapter(groovyjarjarasm.asm.Opcodes.ASM5, methodVisitor, access, name, descriptor) {
@Override
protected void onMethodEnter() {
super.onMethodEnter();
//在方法前插入你想要插入的代码(这个代码在你app工程里)
this.mv.visitMethodInsn(INVOKESTATIC, “com/example/project/AopUtil”, “runStart”, “()V”, false);
}
@Override
protected void onMethodExit(int opcode) {
//在方法结束时插入你想要插入的代码(这个代码在你app工程里)
this.mv.visitMethodInsn(INVOKESTATIC, “com/example/project/AopUtil”, “runEnd”, “()V”, false);
}
};
}
public boolean isInjectClass(String className, String[] interfaces, String superName) {
if (className == null)
return false;
//1、支持runnable和android.os.Handler.Callback
if (interfaces != null) {
for (String inter : interfaces) {
if (“java/lang/Runnable”.equals(inter)
|| “android/os/Handler$Callback”.equals(inter))
return true;
}
}
//2、支持ExtendsAsyncTask
if (“android/os/AsyncTask”.equals(superName)) {
return true;
}
//3、支持Handler.handleMessage
if (“android/os/Handler”.equals(superName)) {
return true;
}
//4、支持Thread.run
if (“java/lang/Thread”.equals(superName)) {
return true;
}
return false;
}
public boolean isInjectMethod(String methodName, String methodDesc) {
if (methodName == null || methodDesc == null)
return false;
//1、runnable和thread的run方法
if (methodName.equals(“run”) && methodDesc.equals("()V"))
return true;
//2、extendedAsyncTask.doInBackground方法
if (methodName.equals(“doInBackground”))
return true;
//3、handler和callback的handleMessage方法
if (methodName.equals(“handleMessage”)) {
return methodDesc.equals("(Landroid/os/Message;)V") || methodDesc.equals("(Landroid/os/Message;)Z");
}
return false;
}
}
复制代码
这里说明一下,在以下代码中,new Runnabl