|
@@ -0,0 +1,102 @@
|
|
|
|
+package com.gradle.ares
|
|
|
|
+
|
|
|
|
+import org.objectweb.asm.ClassVisitor
|
|
|
|
+import org.objectweb.asm.ClassWriter
|
|
|
|
+import org.objectweb.asm.Label
|
|
|
|
+import org.objectweb.asm.MethodVisitor
|
|
|
|
+import org.objectweb.asm.Opcodes
|
|
|
|
+import org.objectweb.asm.commons.GeneratorAdapter
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Created by Glen on 2017/2/8.
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
+public class MethodLifeCycleVisitor extends GeneratorAdapter {
|
|
|
|
+ public final static String LifeClass = "com/uddream/plugin/LifeCycleDelegate";
|
|
|
|
+
|
|
|
|
+ public final static String[] SuperClass = [
|
|
|
|
+ "android/app/Activity",
|
|
|
|
+ "android/support/v4/app/FragmentActivity",
|
|
|
|
+ "android/support/v7/app/AppCompatActivity",
|
|
|
|
+ "android/support/v4/app/Fragment",
|
|
|
|
+ "android/support/v4/app/ListFragment",
|
|
|
|
+ "android/support/v4/app/DialogFragment",
|
|
|
|
+ "android/app/Fragment",
|
|
|
|
+ "android/app/ListFragment",
|
|
|
|
+ "android/app/DialogFragment"
|
|
|
|
+ ] as String[]
|
|
|
|
+
|
|
|
|
+ public final static Agent[] Modify = [
|
|
|
|
+ new Agent("\$getLifeCycleAresDelegate", "()L" + LifeClass + ";"),
|
|
|
|
+ new Agent("onCreate", "(Landroid/os/Bundle;)V"),
|
|
|
|
+ new Agent("onResume", "()V"),
|
|
|
|
+ new Agent("onPause", "()V"),
|
|
|
|
+ new Agent("onDestroy", "()V"),
|
|
|
|
+ new Agent("onSaveInstanceState", "(Landroid/os/Bundle;)V"),
|
|
|
|
+ new Agent("onRestoreInstanceState", "(Landroid/os/Bundle;)V"),
|
|
|
|
+ new Agent("setUserVisibleHint", "(Z)V"),
|
|
|
|
+ new Agent("onHiddenChanged", "(Z)V")
|
|
|
|
+ ] as Agent[]
|
|
|
|
+
|
|
|
|
+ public final static Agent getAgent(String superName, int access, String name, String desc) {
|
|
|
|
+ for (String s : SuperClass) {
|
|
|
|
+ if (s.equals(superName)) {
|
|
|
|
+ for (Agent item : Modify) {
|
|
|
|
+ if (item.name.equals(name) && item.desc.equals(desc)) {
|
|
|
|
+ item.access = access
|
|
|
|
+ return item
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return null
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public final static void addMethods(Set<Agent> agentSet, ClassVisitor cv) {
|
|
|
|
+ cv.visitField(Opcodes.ACC_PUBLIC, "\$lifeCycleAresDelegate", "L" + MethodLifeCycleVisitor.LifeClass + ";", null, null)
|
|
|
|
+ MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "\$getLifeCycleAresDelegate", "()Lcom/uddream/plugin/LifeCycleDelegate;", null, null)
|
|
|
|
+ mv.visitCode()
|
|
|
|
+ mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
|
|
+ mv.visitFieldInsn(Opcodes.GETFIELD, "com/uddream/plugin/LifeCycleDelegate", "\$lifeCycleAresDelegate", "Lcom/uddream/plugin/LifeCycleDelegate;")
|
|
|
|
+ Label label = new Label()
|
|
|
|
+ mv.visitJumpInsn(Opcodes.IFNONNULL, label)
|
|
|
|
+ mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
|
|
+ mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
|
|
+ mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/uddream/plugin/LifeCycleDelegate", "create", "(Ljava/lang/Object;)Lcom/uddream/plugin/LifeCycleDelegate;", false)
|
|
|
|
+ mv.visitFieldInsn(Opcodes.PUTFIELD, "com/uddream/plugin/LifeCycleDelegate", "\$lifeCycleAresDelegate", "Lcom/uddream/plugin/LifeCycleDelegate;")
|
|
|
|
+ mv.visitLabel(label)
|
|
|
|
+ mv.visitVarInsn(Opcodes.ALOAD, 0)
|
|
|
|
+ mv.visitFieldInsn(Opcodes.GETFIELD, "com/uddream/plugin/LifeCycleDelegate", "\$lifeCycleAresDelegate", "Lcom/uddream/plugin/LifeCycleDelegate;")
|
|
|
|
+ mv.visitInsn(Opcodes.ARETURN)
|
|
|
|
+ mv.visitMaxs(0, 0)
|
|
|
|
+ mv.visitEnd()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private int pCount;
|
|
|
|
+ private Agent agent;
|
|
|
|
+
|
|
|
|
+ MethodLifeCycleVisitor(MethodVisitor mv, Agent agent) {
|
|
|
|
+ super(Opcodes.ASM5, mv, agent.access, agent.name, agent.desc)
|
|
|
|
+ this.agent = agent
|
|
|
|
+ for (def item : agent.desc.substring(1, agent.desc.indexOf(")")).split(";")) {
|
|
|
|
+ if (!item.equals("")) this.pCount++
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ void visitCode() {
|
|
|
|
+ super.visitCode()
|
|
|
|
+ //for (int i = 0; i < pCount; i++) loadArg(i)
|
|
|
|
+ //visitMethodInsn(Opcodes.INVOKESTATIC, LifeClass, agent.name, agent.desc, false)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void visitInsn(int opcode) {
|
|
|
|
+ if (opcode == Opcodes.RETURN) {
|
|
|
|
+ //for (int i = 0; i < pCount; i++) loadArg(i)
|
|
|
|
+ //visitMethodInsn(Opcodes.INVOKESTATIC, LifeClass, agent.name, agent.desc, false)
|
|
|
|
+ }
|
|
|
|
+ super.visitInsn(opcode);
|
|
|
|
+ }
|
|
|
|
+}
|