|
@@ -5,14 +5,13 @@ import org.objectweb.asm.FieldVisitor
|
|
import org.objectweb.asm.Label
|
|
import org.objectweb.asm.Label
|
|
import org.objectweb.asm.MethodVisitor
|
|
import org.objectweb.asm.MethodVisitor
|
|
import org.objectweb.asm.Opcodes
|
|
import org.objectweb.asm.Opcodes
|
|
|
|
+import org.objectweb.asm.commons.GeneratorAdapter
|
|
|
|
|
|
/**
|
|
/**
|
|
* Created by Glen on 2017/2/8.
|
|
* Created by Glen on 2017/2/8.
|
|
*/
|
|
*/
|
|
|
|
|
|
-public class MethodLifeCycleVisitor extends MethodVisitor {
|
|
|
|
- public final static String LifeClass = "com/uddream/plugin/LifeCycleDelegate";
|
|
|
|
- public final static String GetLifeMethod = "\$getLifeCycleAresDelegate";
|
|
|
|
|
|
+public class MethodLifeCycleVisitor extends MethodBaseVisitor {
|
|
|
|
|
|
public final static String[] SuperClass = [
|
|
public final static String[] SuperClass = [
|
|
"android/app/Activity",
|
|
"android/app/Activity",
|
|
@@ -27,19 +26,21 @@ public class MethodLifeCycleVisitor extends MethodVisitor {
|
|
] as String[]
|
|
] as String[]
|
|
|
|
|
|
public final static MethodModel[] Modify = [
|
|
public final static MethodModel[] Modify = [
|
|
- new MethodModel("onCreate", "(Landroid/os/Bundle;)V"),
|
|
|
|
- new MethodModel("onResume", "()V"),
|
|
|
|
- new MethodModel("onPause", "()V"),
|
|
|
|
- new MethodModel("onDestroy", "()V"),
|
|
|
|
- new MethodModel("onSaveInstanceState", "(Landroid/os/Bundle;)V"),
|
|
|
|
- new MethodModel("onRestoreInstanceState", "(Landroid/os/Bundle;)V"),
|
|
|
|
- new MethodModel("setUserVisibleHint", "(Z)V"),
|
|
|
|
- new MethodModel("onHiddenChanged", "(Z)V")
|
|
|
|
|
|
+ new MethodModel("onCreate", "(Landroid/os/Bundle;)V", 1),
|
|
|
|
+ new MethodModel("onResume", "()V", 0),
|
|
|
|
+ new MethodModel("onPause", "()V", 0),
|
|
|
|
+ new MethodModel("onDestroy", "()V", 0),
|
|
|
|
+ new MethodModel("onSaveInstanceState", "(Landroid/os/Bundle;)V", 1),
|
|
|
|
+ new MethodModel("onRestoreInstanceState", "(Landroid/os/Bundle;)V", 1),
|
|
|
|
+ new MethodModel("setUserVisibleHint", "(Z)V", 1),
|
|
|
|
+ new MethodModel("onHiddenChanged", "(Z)V", 1)
|
|
] as MethodModel[]
|
|
] as MethodModel[]
|
|
|
|
|
|
- public static MethodModel getAgent(String className, String superName, String name, String desc) {
|
|
|
|
|
|
+ public
|
|
|
|
+ static MethodModel getAgent(int access, String className, String superName, String name, String desc) {
|
|
for (MethodModel item : Modify) {
|
|
for (MethodModel item : Modify) {
|
|
if (item.name.equals(name) && item.desc.equals(desc)) {
|
|
if (item.name.equals(name) && item.desc.equals(desc)) {
|
|
|
|
+ item.access = access
|
|
item.className = className
|
|
item.className = className
|
|
item.superName = superName
|
|
item.superName = superName
|
|
return item
|
|
return item
|
|
@@ -54,24 +55,20 @@ public class MethodLifeCycleVisitor extends MethodVisitor {
|
|
for (MethodModel agent : Modify) {
|
|
for (MethodModel agent : Modify) {
|
|
if (!agentSet.contains(agent)) {
|
|
if (!agentSet.contains(agent)) {
|
|
//method
|
|
//method
|
|
- int count = 0;
|
|
|
|
- for (def item : agent.desc.substring(1, agent.desc.indexOf(")")).split(";")) {
|
|
|
|
- if (!item.equals("")) count++
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, agent.name, agent.desc, null, null)
|
|
MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, agent.name, agent.desc, null, null)
|
|
- mv.visitCode()
|
|
|
|
- mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
|
|
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, GetLifeMethod, "()L" + LifeClass + ";", false)
|
|
|
|
- for (int i = 1; i <= count; i++) mv.visitVarInsn(Opcodes.ALOAD, i)
|
|
|
|
- mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, LifeClass, agent.name, agent.desc, false)
|
|
|
|
|
|
+ GeneratorAdapter adapter = new GeneratorAdapter(Opcodes.ASM5, mv, Opcodes.ACC_PUBLIC, agent.name, agent.desc)
|
|
|
|
+ adapter.visitCode()
|
|
|
|
+ adapter.loadThis()
|
|
|
|
+ adapter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, className, AresValue.GetLifeMethod, "()L" + AresValue.LifeClass + ";", false)
|
|
|
|
+ for (int i = 0; i < agent.count; i++) adapter.loadArg(i)
|
|
|
|
+ adapter.visitMethodInsn(Opcodes.INVOKEVIRTUAL, AresValue.LifeClass, agent.name, agent.desc, false)
|
|
|
|
|
|
- mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
|
|
- for (int i = 1; i <= count; i++) mv.visitVarInsn(Opcodes.ALOAD, i)
|
|
|
|
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, agent.name, agent.desc, false)
|
|
|
|
- mv.visitInsn(Opcodes.RETURN)
|
|
|
|
- mv.visitMaxs(0, 0)
|
|
|
|
- mv.visitEnd()
|
|
|
|
|
|
+ adapter.loadThis()
|
|
|
|
+ for (int i = 0; i < agent.count; i++) adapter.loadArg(i)
|
|
|
|
+ adapter.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, agent.name, agent.desc, false)
|
|
|
|
+ adapter.visitInsn(Opcodes.RETURN)
|
|
|
|
+ adapter.visitMaxs(0, 0)
|
|
|
|
+ adapter.visitEnd()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -83,12 +80,12 @@ public class MethodLifeCycleVisitor extends MethodVisitor {
|
|
private static void addLifeCycleFieldMethod(String className, ClassVisitor cv) {
|
|
private static void addLifeCycleFieldMethod(String className, ClassVisitor cv) {
|
|
//desc
|
|
//desc
|
|
String fieldName = "\$lifeCycleAresDelegate"
|
|
String fieldName = "\$lifeCycleAresDelegate"
|
|
- String fieldDesc = "L" + LifeClass + ";"
|
|
|
|
|
|
+ String fieldDesc = "L" + AresValue.LifeClass + ";"
|
|
//field
|
|
//field
|
|
FieldVisitor fv = cv.visitField(Opcodes.ACC_PUBLIC, fieldName, fieldDesc, null, null)
|
|
FieldVisitor fv = cv.visitField(Opcodes.ACC_PUBLIC, fieldName, fieldDesc, null, null)
|
|
fv.visitEnd()
|
|
fv.visitEnd()
|
|
//method
|
|
//method
|
|
- MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, GetLifeMethod, "()" + fieldDesc, null, null)
|
|
|
|
|
|
+ MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, AresValue.GetLifeMethod, "()" + fieldDesc, null, null)
|
|
mv.visitCode()
|
|
mv.visitCode()
|
|
mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
mv.visitFieldInsn(Opcodes.GETFIELD, className, fieldName, fieldDesc)
|
|
mv.visitFieldInsn(Opcodes.GETFIELD, className, fieldName, fieldDesc)
|
|
@@ -96,7 +93,7 @@ public class MethodLifeCycleVisitor extends MethodVisitor {
|
|
mv.visitJumpInsn(Opcodes.IFNONNULL, label)
|
|
mv.visitJumpInsn(Opcodes.IFNONNULL, label)
|
|
mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, LifeClass, "create", "(Ljava/lang/Object;)" + fieldDesc, false)
|
|
|
|
|
|
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, AresValue.LifeClass, "create", "(Ljava/lang/Object;)" + fieldDesc, false)
|
|
mv.visitFieldInsn(Opcodes.PUTFIELD, className, fieldName, fieldDesc)
|
|
mv.visitFieldInsn(Opcodes.PUTFIELD, className, fieldName, fieldDesc)
|
|
mv.visitLabel(label)
|
|
mv.visitLabel(label)
|
|
mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
@@ -106,25 +103,17 @@ public class MethodLifeCycleVisitor extends MethodVisitor {
|
|
mv.visitEnd()
|
|
mv.visitEnd()
|
|
}
|
|
}
|
|
|
|
|
|
- private int pCount;
|
|
|
|
- private String className;
|
|
|
|
- private MethodModel agent;
|
|
|
|
-
|
|
|
|
MethodLifeCycleVisitor(MethodVisitor mv, MethodModel agent) {
|
|
MethodLifeCycleVisitor(MethodVisitor mv, MethodModel agent) {
|
|
- super(Opcodes.ASM5, mv)
|
|
|
|
|
|
+ super(mv, agent)
|
|
this.agent = agent
|
|
this.agent = agent
|
|
- this.className = agent.className
|
|
|
|
- for (def item : agent.desc.substring(1, agent.desc.indexOf(")")).split(";")) {
|
|
|
|
- if (!item.equals("")) this.pCount++
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
void visitCode() {
|
|
void visitCode() {
|
|
super.visitCode()
|
|
super.visitCode()
|
|
visitVarInsn(Opcodes.ALOAD, 0)
|
|
visitVarInsn(Opcodes.ALOAD, 0)
|
|
- visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.className, GetLifeMethod, "()L" + LifeClass + ";", false)
|
|
|
|
- for (int i = 1; i <= pCount; i++) visitVarInsn(Opcodes.ALOAD, i)
|
|
|
|
- visitMethodInsn(Opcodes.INVOKEVIRTUAL, LifeClass, agent.name, agent.desc, false)
|
|
|
|
|
|
+ visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.agent.className, AresValue.GetLifeMethod, "()L" + AresValue.LifeClass + ";", false)
|
|
|
|
+ for (int i = 0; i < this.agent.count; i++) loadArg(i)
|
|
|
|
+ visitMethodInsn(Opcodes.INVOKEVIRTUAL, AresValue.LifeClass, this.agent.name, this.agent.desc, false)
|
|
}
|
|
}
|
|
}
|
|
}
|