Skip to content

Commit 5189665

Browse files
author
Vens Chen
committed
add intercept
1 parent 34bdbbf commit 5189665

File tree

20 files changed

+458
-111
lines changed

20 files changed

+458
-111
lines changed

README.md

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,27 @@ ttree {
6161
```
6262

6363
**注意:** ttree,isDebug,matchData,AnnotationPath,AnnotationReceiver,ClassReceiver
64-
ClassFilter,ClassName,MethodName,ContainName,InterfaceName,MethodDes,Override,MethodVisitor,
64+
ClassFilter,ClassName,MethodName,ContainName,InterfaceName,MethodDes,Override,MethodVisitor,Intercept
6565
这些约定的拼写不能错误。
6666

6767
**AnnotationPath:** String类型,使用自定义注解时,注解所在的包路径
6868

69-
**AnnotationReceiver:** String类型,使用自定义注解时,处理注解的类,必须使用全路径,
70-
处理的方法必须是:`public static void onMethodExitForAnnotation``public static void onMethodExitForAnnotation`
71-
参数类型必须是:`(String annotationName,String methodName, String jsonValue)`,jsonValue的结构是Hashmap<String,Object>,对应注解的key和value。
72-
73-
**ClassReceiver:** String类型,使用匹配规则时的处理类,必须使用全路径,可以与AnnotationReceiver同名,
74-
处理的方法必须是:`public static void onMethodEnterForClass``public static void onMethodExitForClass`
75-
参数类型必须是:`(Object object,String className,String methodName,Object[] objects)`
76-
object 表示该方法的类对象指针,即this(注意内部类的this),静态方法该值为null,className表示全路径类名(注意内部类的类名),
77-
methodName表示方法名,objects存放了methodName这个方法的参数值,
78-
自定义ClassReceiver之后,拓展包里面的ClassReceiver将不再接收。
69+
**AnnotationReceiver:** String类型,使用自定义注解时,处理注解的类,必须使用全路径。
70+
处理的方法:
71+
匹配注解,方法进入时调用`public static void onMethodExitForAnnotation(String annotationName,String methodName, String jsonValue)`
72+
匹配注解,方法拦截时调用`public static Object onInterceptForAnnotation(String annotationName, String methodName, String jsonValue, String returnType)`
73+
匹配注解,方法退出时调用`public static void onMethodExitForAnnotation(String annotationName,String methodName, String jsonValue)`
74+
其中需要注意,方法名和参数类型,返回类型必须与上面的一致,jsonValue的结构是Hashmap<String,Object>,对应注解的key和value,当使用拦截规则时候,onMethodExitForAnnotation将不会再被调用。
75+
76+
**ClassReceiver:** String类型,使用匹配规则时的处理类,必须使用全路径,可以与AnnotationReceiver同名。
77+
处理的方法:
78+
根据类名等规则匹配,方法进入时调用`public static void onMethodEnterForClass(Object object,String className,String methodName,Object[] objects)`
79+
根据类名等规则匹配,方法拦截时调用`public static Object onInterceptForClass(Object object,String className,String methodName,Object[] objects,String returnType)`
80+
根据类名等规则匹配,方法退出时调用`public static void onMethodExitForClass(Object object,String className,String methodName,Object[] objects)`
81+
82+
其中需要注意,方法名和参数类型,返回类型必须与上面的一致,object 表示该方法的类对象指针,即this(注意内部类的this),静态方法该值为null,
83+
className表示全路径类名(注意内部类的类名),methodName表示方法名,objects存放了methodName这个方法的参数值,
84+
自定义ClassReceiver之后,拓展包里面的ClassReceiver将不再接收,当使用拦截规则时候,onMethodExitForAnnotation将不会再被调用。。
7985
8086
**ClassName:** String类型,类名,全路径
8187

@@ -87,10 +93,12 @@ ClassFilter,ClassName,MethodName,ContainName,InterfaceName,MethodDes
8793

8894
**MethodDes:** String类型,方法的描述符
8995

90-
**Override:** boolean类型,是否重载MethodVisitor(高级用法,需要对asm有一定的了解)
96+
**Override:** boolean类型,是否重载MethodVisitor(高级用法,需要对asm有一定的了解,不推荐使用
9197

9298
**MethodVisitor:** 在Override为true的时候使用(参考demo)
9399

100+
**Intercept:**boolean类型,是否需要拦截方法(如果需要使用注解来拦截方法,注解需要定义一个boolean类型的key为onIntercept,在使用的地方赋值为true)
101+
94102
**匹配规则优先级:** ClassName > InterfaceName > ContainName
95103

96104

@@ -159,6 +167,9 @@ TtreePlugin.setOnCutListener(new TtreePlugin.IOnCutListener() {
159167
}
160168
});
161169
```
170+
**仿抖动**
171+
在需要防抖动的地方添加`@Debounce(time = 1000,onIntercept = true)`
172+
time为抖动的时间
162173

163174

164175
**动态权限申请**

app/build.gradle

Lines changed: 69 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -28,69 +28,73 @@ dependencies {
2828
}
2929

3030

31-
buildscript {
32-
repositories {
33-
maven {
34-
url uri('../repo')
35-
}
36-
}
37-
dependencies {
38-
classpath 'com.threetrees.plugin:plugin:1.0.0'
39-
}
40-
}
41-
42-
apply plugin: 'ttreeplugin'
43-
44-
import com.threetrees.plugin.asm.AutoMethodVisitor
45-
import org.objectweb.asm.MethodVisitor
46-
import org.objectweb.asm.Opcodes
47-
48-
ttree {
49-
isDebug = true
50-
//具体配置
51-
matchData = [
52-
'AnnotationPath' : 'com.threetree.ttreeplugin.annotation',
53-
'AnnotationReceiver' : 'com.threetree.ttreeplugin.MyReceiver',
54-
'ClassReceiver' : 'com.threetree.ttreeplugin.MyReceiver',
55-
'ClassFilter' : [
56-
//根据类型匹配
57-
['ClassName' : 'com/threetree/ttreeplugin/MainActivity',
58-
'MethodName': 'testClassName', 'MethodDes': '()V'],
59-
//根据类型匹配
60-
['ClassName' : 'com/threetree/ttreeplugin/MainActivity',
61-
'MethodName': 'testBoolean', 'MethodDes': '(Z)V'],
62-
//根据关键字匹配
63-
['ContainName' : 'Activity',
64-
'MethodName': 'testContainName', 'MethodDes': '(Ljava/lang/String;)V'],
65-
//根据接口名匹配
66-
['InterfaceName': 'android/view/View$OnClickListener',
67-
'MethodName': 'onClick', 'MethodDes': '(Landroid/view/View;)V'],
68-
//根据类型匹配
69-
['ClassName' : 'com/threetree/ttreeplugin/MainActivity',
70-
'MethodName': 'testOverride', 'MethodDes': '()V', 'Override' : true]
71-
],
72-
//插入的字节码,方法的执行顺序visitAnnotation->onMethodEnter->onMethodExit
73-
'MethodVisitor': {
74-
MethodVisitor methodVisitor, int access, String name, String desc, String className ->
75-
AutoMethodVisitor adapter = new AutoMethodVisitor(methodVisitor, access, name, desc, className) {
76-
@Override
77-
protected void onMethodEnter() {
78-
super.onMethodEnter();
79-
if("testOverride".equals(name))
80-
{
81-
methodVisitor.visitLdcInsn(name)
82-
methodVisitor.visitLdcInsn("========start=========")
83-
methodVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, "android/util/Log", "e", "(Ljava/lang/String;Ljava/lang/String;)I", false)
84-
}
85-
}
86-
87-
@Override
88-
protected void onMethodExit(int opcode) {
89-
super.onMethodExit(opcode)
90-
}
91-
}
92-
return adapter
93-
}
94-
]
95-
}
31+
//buildscript {
32+
// repositories {
33+
// maven {
34+
// url uri('../repo')
35+
// }
36+
// }
37+
// dependencies {
38+
// classpath 'com.threetrees.plugin:plugin:1.0.0'
39+
// }
40+
//}
41+
//
42+
//apply plugin: 'ttreeplugin'
43+
//
44+
//import com.threetrees.plugin.asm.AutoMethodVisitor
45+
//import org.objectweb.asm.MethodVisitor
46+
//import org.objectweb.asm.Opcodes
47+
//
48+
//ttree {
49+
// isDebug = true
50+
// //具体配置
51+
// matchData = [
52+
//// 'AnnotationPath' : 'com.threetree.ttreeplugin.annotation',
53+
//// 'AnnotationReceiver' : 'com.threetree.ttreeplugin.MyReceiver',
54+
//// 'ClassReceiver' : 'com.threetree.ttreeplugin.MyReceiver',
55+
// 'ClassFilter' : [
56+
// //根据类型匹配
57+
// ['ClassName' : 'com/threetree/ttreeplugin/MainActivity',
58+
// 'MethodName': 'testClassName', 'MethodDes': '()V'],
59+
// //根据类型匹配
60+
// ['ClassName' : 'com/threetree/ttreeplugin/MainActivity',
61+
// 'MethodName': 'testBoolean', 'MethodDes': '(Z)V'],
62+
// //根据关键字匹配
63+
// ['ContainName' : 'Activity',
64+
// 'MethodName': 'testContainName', 'MethodDes': '(Ljava/lang/String;)V'],
65+
// //根据接口名匹配
66+
// ['InterfaceName': 'android/view/View$OnClickListener',
67+
// 'MethodName': 'onClick', 'MethodDes': '(Landroid/view/View;)V'],
68+
// //根据类型匹配,外部配置覆盖
69+
// ['ClassName' : 'com/threetree/ttreeplugin/MainActivity',
70+
// 'MethodName': 'testOverride', 'MethodDes': '()V', 'Override' : true],
71+
// //根据类型匹配,拦截方法
72+
// ['ClassName' : 'com/threetree/ttreeplugin/MainActivity',
73+
// 'MethodName': 'testInterceptForClass', 'MethodDes': '()V', 'Intercept' : true]
74+
// ],
75+
// //插入的字节码,方法的执行顺序visitAnnotation->onMethodEnter->onMethodExit
76+
// 'MethodVisitor': {
77+
// MethodVisitor mv, int access, String name, String desc, String className ->
78+
// AutoMethodVisitor adapter = new AutoMethodVisitor(mv, access, name, desc, className) {
79+
// @Override
80+
// protected void onMethodEnter() {
81+
// super.onMethodEnter();
82+
// if("testOverride".equals(name))
83+
// {
84+
//
85+
// mv.visitLdcInsn(name)
86+
// mv.visitLdcInsn("========start=========")
87+
// mv.visitMethodInsn(Opcodes.INVOKESTATIC, "android/util/Log", "e", "(Ljava/lang/String;Ljava/lang/String;)I", false)
88+
// }
89+
// }
90+
//
91+
// @Override
92+
// protected void onMethodExit(int opcode) {
93+
// super.onMethodExit(opcode)
94+
// }
95+
// }
96+
// return adapter
97+
// }
98+
// ]
99+
//}
96100

app/src/main/java/com/threetree/ttreeplugin/MainActivity.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import android.view.View;
66

77
import com.threetree.pluginutil.annotation.Cut;
8+
import com.threetree.pluginutil.annotation.Debounce;
89
import com.threetree.pluginutil.annotation.Permission;
910
import com.threetree.pluginutil.annotation.TimeCost;
1011
import com.threetree.pluginutil.permission.PermissionConsts;
@@ -77,7 +78,18 @@ public void testOverride()
7778
@Override
7879
public void onClick(View v)
7980
{
81+
int id = v.getId();
82+
}
8083

84+
@Debounce(time = 1000,onIntercept = true)
85+
public int testIntercept()
86+
{
87+
int id = 234;
88+
return id;
8189
}
8290

91+
public void testInterceptForClass()
92+
{
93+
int id = 234;
94+
}
8395
}

app/src/main/java/com/threetree/ttreeplugin/MyReceiver.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,10 @@ private static HashMap<String,Object> jsonToMap(String jsonStr)
9090
return new Gson()
9191
.fromJson(jsonStr, new TypeToken<HashMap<String,Object>>(){}.getType());
9292
}
93+
94+
95+
public static boolean shouldDoClick()
96+
{
97+
return false;
98+
}
9399
}

plugin/build.gradle

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
apply plugin: 'groovy'
22
apply plugin: 'java'//导入java插件用于,编译打包我们的插件
3-
apply plugin: 'maven'//maven插件,用于上传插件到仓库
3+
//apply plugin: 'maven'//maven插件,用于上传插件到仓库
44

5-
//// JitPack Maven
6-
//apply plugin: 'com.github.dcendents.android-maven'
7-
//// Your Group
8-
//group='com.github.chenthreetrees'
5+
// JitPack Maven
6+
apply plugin: 'com.github.dcendents.android-maven'
7+
// Your Group
8+
group='com.github.chenthreetrees'
99

1010
compileGroovy {
1111
sourceCompatibility = 1.7
@@ -21,21 +21,21 @@ dependencies {
2121
compile 'org.ow2.asm:asm-commons:5.0.3'
2222
}
2323

24-
repositories {
25-
// jcenter()
26-
mavenCentral()
27-
}
28-
29-
group='com.threetrees.plugin'
30-
version='1.0.0'
31-
32-
//uploadArchives 类型是upload,这个task不是'maven'创建的
33-
//而是'maven'定义了一个rule,而后由我们自己创建的
34-
uploadArchives{
35-
//本地仓库的一种
36-
repositories{
37-
mavenDeployer {
38-
repository(url: uri('../repo'))
39-
}
40-
}
41-
}
24+
//repositories {
25+
//// jcenter()
26+
// mavenCentral()
27+
//}
28+
//
29+
//group='com.threetrees.plugin'
30+
//version='1.0.0'
31+
//
32+
////uploadArchives 类型是upload,这个task不是'maven'创建的
33+
////而是'maven'定义了一个rule,而后由我们自己创建的
34+
//uploadArchives{
35+
// //本地仓库的一种
36+
// repositories{
37+
// mavenDeployer {
38+
// repository(url: uri('../repo'))
39+
// }
40+
// }
41+
//}

plugin/src/main/groovy/com/threetrees/plugin/Controller.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public class Controller {
7474
methodVisitor = visitor
7575
}
7676

77-
static Closure getAppMethodVistor() {
77+
static Closure getMethodVistor() {
7878
return methodVisitor
7979
}
8080

plugin/src/main/groovy/com/threetrees/plugin/TtreePlugin.groovy

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class TtreePlugin implements Plugin<Project> {
4444
String methodName = map.get("MethodName")
4545
String methodDes = map.get("MethodDes")
4646
boolean override = false
47+
boolean intercept = false
4748
// 全类名
4849
if (!TextUtil.isEmpty(className)){
4950
className = TextUtil.changeClassNameSeparator(className)
@@ -58,13 +59,19 @@ class TtreePlugin implements Plugin<Project> {
5859
override = map.get("Override")
5960
}
6061

62+
if(map.containsKey("Intercept"))
63+
{
64+
intercept = map.get("Intercept")
65+
}
66+
6167
AutoClassFilter classFilter = new AutoClassFilter()
6268
classFilter.setContainName(containName)
6369
classFilter.setClassName(className)
6470
classFilter.setInterfaceName(interfaceName)
6571
classFilter.setMethodName(methodName)
6672
classFilter.setMethodDes(methodDes)
6773
classFilter.setOverride(override)
74+
classFilter.setIntercept(intercept)
6875
Controller.addClassFilter(classFilter)
6976

7077
Logger.info('应用传递过来的数据->' + '\n-containName:' + containName + '\n-className:' + className +

plugin/src/main/groovy/com/threetrees/plugin/asm/AutoClassFilter.groovy

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ class AutoClassFilter {
1010
String MethodName
1111
String MethodDes
1212
boolean Override
13+
boolean Intercept
1314
}

0 commit comments

Comments
 (0)