MethodLifeCycleVisitor.groovy 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. package com.gradle.ares
  2. import org.gradle.api.logging.Logging
  3. import org.objectweb.asm.ClassVisitor
  4. import org.objectweb.asm.FieldVisitor
  5. import org.objectweb.asm.Label
  6. import org.objectweb.asm.MethodVisitor
  7. import org.objectweb.asm.Opcodes
  8. /**
  9. * Created by Glen on 2017/2/8.
  10. */
  11. public class MethodLifeCycleVisitor extends MethodVisitor {
  12. public final static String LifeClass = "com/uddream/plugin/LifeCycleDelegate";
  13. public final static String GetLifeMethod = "\$getLifeCycleAresDelegate";
  14. public final static String[] SuperClass = [
  15. "android/app/Activity",
  16. "android/support/v4/app/FragmentActivity",
  17. "android/support/v7/app/AppCompatActivity",
  18. "android/support/v4/app/Fragment",
  19. "android/support/v4/app/ListFragment",
  20. "android/support/v4/app/DialogFragment",
  21. "android/app/Fragment",
  22. "android/app/ListFragment",
  23. "android/app/DialogFragment"
  24. ] as String[]
  25. public final static Agent[] Modify = [
  26. new Agent("onCreate", "(Landroid/os/Bundle;)V"),
  27. new Agent("onResume", "()V"),
  28. new Agent("onPause", "()V"),
  29. new Agent("onDestroy", "()V"),
  30. new Agent("onSaveInstanceState", "(Landroid/os/Bundle;)V"),
  31. new Agent("onRestoreInstanceState", "(Landroid/os/Bundle;)V"),
  32. new Agent("setUserVisibleHint", "(Z)V"),
  33. new Agent("onHiddenChanged", "(Z)V")
  34. ] as Agent[]
  35. public final static Agent getAgent(String superName, int access, String name, String desc) {
  36. for (String s : SuperClass) {
  37. if (s.equals(superName)) {
  38. for (Agent item : Modify) {
  39. if (item.name.equals(name) && item.desc.equals(desc)) {
  40. item.access = access
  41. return item
  42. }
  43. }
  44. break
  45. }
  46. }
  47. return null
  48. }
  49. public final
  50. static void addMethods(Set<Agent> agentSet, String name, String superName, ClassVisitor cv) {
  51. addLifeCycleFieldMethod(cv)
  52. for (Agent agent : Modify) {
  53. if (!agentSet.contains(agent)) {
  54. // //method
  55. // int count = 0;
  56. // for (def item : agent.desc.substring(1, agent.desc.indexOf(")")).split(";")) {
  57. // if (!item.equals("")) count++
  58. // }
  59. //
  60. // MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, agent.name, agent.desc, null, null)
  61. // mv.visitCode()
  62. // mv.visitVarInsn(Opcodes.ALOAD, 0)
  63. // mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, name, GetLifeMethod, "()L" + LifeClass + ";", false)
  64. // for (int i = 1; i <= count; i++) mv.visitVarInsn(Opcodes.ALOAD, i)
  65. // mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, LifeClass, agent.name, agent.desc, false)
  66. //
  67. // mv.visitVarInsn(Opcodes.ALOAD, 0)
  68. // for (int i = 1; i <= count; i++) mv.visitVarInsn(Opcodes.ALOAD, i)
  69. // mv.visitMethodInsn(Opcodes.INVOKESPECIAL, superName, agent.name, agent.desc, false)
  70. // mv.visitInsn(Opcodes.RETURN)
  71. // mv.visitMaxs(0, 0)
  72. // mv.visitEnd()
  73. }
  74. }
  75. }
  76. /**
  77. * 注入代理字段及初始化方法
  78. * @param cv
  79. */
  80. private final static void addLifeCycleFieldMethod(ClassVisitor cv) {
  81. //desc
  82. String fieldName = "\$lifeCycleAresDelegate"
  83. String fieldDesc = "L" + LifeClass + ";"
  84. //field
  85. FieldVisitor fv = cv.visitField(Opcodes.ACC_PUBLIC, fieldName, fieldDesc, null, null)
  86. fv.visitEnd()
  87. //method
  88. MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, GetLifeMethod, "()" + fieldDesc, null, null)
  89. mv.visitCode()
  90. mv.visitVarInsn(Opcodes.ALOAD, 0)
  91. mv.visitFieldInsn(Opcodes.GETFIELD, LifeClass, fieldName, fieldDesc)
  92. Label label = new Label()
  93. mv.visitJumpInsn(Opcodes.IFNONNULL, label)
  94. mv.visitVarInsn(Opcodes.ALOAD, 0)
  95. mv.visitVarInsn(Opcodes.ALOAD, 0)
  96. mv.visitMethodInsn(Opcodes.INVOKESTATIC, LifeClass, "create", "(Ljava/lang/Object;)" + fieldDesc, false)
  97. mv.visitFieldInsn(Opcodes.PUTFIELD, LifeClass, fieldName, fieldDesc)
  98. mv.visitLabel(label)
  99. mv.visitVarInsn(Opcodes.ALOAD, 0)
  100. mv.visitFieldInsn(Opcodes.GETFIELD, LifeClass, fieldName, fieldDesc)
  101. mv.visitInsn(Opcodes.ARETURN)
  102. mv.visitMaxs(0, 0)
  103. mv.visitEnd()
  104. }
  105. private int pCount;
  106. private String name;
  107. private Agent agent;
  108. MethodLifeCycleVisitor(MethodVisitor mv, String name, Agent agent) {
  109. super(Opcodes.ASM5, mv)
  110. this.agent = agent
  111. this.name = name
  112. for (def item : agent.desc.substring(1, agent.desc.indexOf(")")).split(";")) {
  113. if (!item.equals("")) this.pCount++
  114. }
  115. }
  116. @Override
  117. void visitCode() {
  118. super.visitCode()
  119. visitVarInsn(Opcodes.ALOAD, 0)
  120. visitMethodInsn(Opcodes.INVOKEVIRTUAL, name, GetLifeMethod, "()L" + LifeClass + ";", false)
  121. for (int i = 1; i <= pCount; i++) visitVarInsn(Opcodes.ALOAD, i)
  122. visitMethodInsn(Opcodes.INVOKEVIRTUAL, LifeClass, agent.name, agent.desc, false)
  123. }
  124. }