123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- package com.gradle.ares
- import org.objectweb.asm.ClassVisitor
- import org.objectweb.asm.FieldVisitor
- import org.objectweb.asm.Label
- import org.objectweb.asm.MethodVisitor
- import org.objectweb.asm.Opcodes
- /**
- * 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 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 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")
- ] as MethodModel[]
- public static MethodModel getAgent(String className, String superName, String name, String desc) {
- for (String s : SuperClass) {
- if (s.equals(superName)) {
- for (MethodModel item : Modify) {
- if (item.name.equals(name) && item.desc.equals(desc)) {
- item.className = className
- item.superName = superName
- return item
- }
- }
- break
- }
- }
- return null
- }
- public static void addMethods(Set<MethodModel> agentSet, String className, String superName, ClassVisitor cv) {
- addLifeCycleFieldMethod(className, cv)
- for (MethodModel agent : Modify) {
- if (!agentSet.contains(agent)) {
- //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)
- 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)
- 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()
- }
- }
- }
- /**
- * 注入代理字段及初始化方法
- * @param cv
- */
- private static void addLifeCycleFieldMethod(String className, ClassVisitor cv) {
- //desc
- String fieldName = "\$lifeCycleAresDelegate"
- String fieldDesc = "L" + LifeClass + ";"
- //field
- FieldVisitor fv = cv.visitField(Opcodes.ACC_PUBLIC, fieldName, fieldDesc, null, null)
- fv.visitEnd()
- //method
- MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, GetLifeMethod, "()" + fieldDesc, null, null)
- mv.visitCode()
- mv.visitVarInsn(Opcodes.ALOAD, 0)
- mv.visitFieldInsn(Opcodes.GETFIELD, className, fieldName, fieldDesc)
- Label label = new Label()
- mv.visitJumpInsn(Opcodes.IFNONNULL, label)
- mv.visitVarInsn(Opcodes.ALOAD, 0)
- mv.visitVarInsn(Opcodes.ALOAD, 0)
- mv.visitMethodInsn(Opcodes.INVOKESTATIC, LifeClass, "create", "(Ljava/lang/Object;)" + fieldDesc, false)
- mv.visitFieldInsn(Opcodes.PUTFIELD, className, fieldName, fieldDesc)
- mv.visitLabel(label)
- mv.visitVarInsn(Opcodes.ALOAD, 0)
- mv.visitFieldInsn(Opcodes.GETFIELD, className, fieldName, fieldDesc)
- mv.visitInsn(Opcodes.ARETURN)
- mv.visitMaxs(0, 0)
- mv.visitEnd()
- }
- private int pCount;
- private String className;
- private MethodModel agent;
- MethodLifeCycleVisitor(MethodVisitor mv, MethodModel agent) {
- super(Opcodes.ASM5, mv)
- this.agent = agent
- this.className = agent.className
- for (def item : agent.desc.substring(1, agent.desc.indexOf(")")).split(";")) {
- if (!item.equals("")) this.pCount++
- }
- }
- @Override
- void visitCode() {
- super.visitCode()
- 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)
- }
- }
|