Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

项目名:自动埋点

项目介绍: 通过插装方法,实现自动埋点,在需要获取方法信息的时候,可通过服务端下发指令, 来根据方法的参数和返回值来判断方法中可能存在的问题。

使用方式:

一.添加依赖 annotationProcessor "com.guuidea.plugin:processor:0.2.3-SNAPSHOT" implementation "com.guuidea.plugin:tracker-android:0.2.6-SNAPSHOT" //android

二.初始化,在application中添加如下初始化,addTracker用来表示需要添加的埋点,uploadLogInfo用来自定义上传接口。 如果addTracker返回true则不会执行uploadLogInfo方法,当返回false的时候,下次进入app会统一请求uploadLogInfo,并根据listener判断上传失败或成功

Trackers.instance().setTrackerAddListener(new TrackerAddListener() { @Override public boolean addTracker(String className, String methodName,String tag,Object... args) { return false; } }).setTrackerUploadListener(new DefaultTrackerUploadListener() { @Override public void uploadLogInfo(List list, TrackerResultListener listener) { super.uploadLogInfo(list, listener); String json = TrackerUtils.getTraceLogJson(list); if(listener!=null){ listener.onSuccess(); } } }).setDebug(BuildConfig.DEBUG).init();

三.在需要的类或方法上用Tracker去注解,同时Tracker有几个参数可选 1.enable 是否开启 2.group 当前所属分组 3.tag 标签信息 4.injectorType 所用的注解方法(暂时不需要修改,只支持InjectType.DEFAULT) 5.injectRule 使用方法 injectRule = @InjectRule(regex = "method+\d*")

四.举一个例子 @Tracker public class Server extends BaseServer { public Server() {

}

public String[] getSomeThings() {
    System.out.println("不只是这么简单");
    String[] tt = {"ddd", "sss"};
    return tt;
}

@Tracker(enable = false)
public char getSomeThingsUnTracker() {
    return '1';
}

}

这个例子中 getSomeThings()方法会得到注入,getSomeThingsUnTracker()方法则不会,(后续会添加配置规则功能) 得到的效果是: public String[] getSomeThings() { if (TrackerDefaultInjector.isEnable("com.guuidea.tracker.Server", "getSomeThings", new String[0], new String[0], new Object[0])) { TrackerDefaultInjector.insertFront(this, "com.guuidea.tracker.Server", "getSomeThings", new String[0], new String[0], "", new Object[0]); }

String[] tt = new String[]{"ddd", "sss"};
if (TrackerDefaultInjector.isEnable("com.guuidea.tracker.Server", "getSomeThings", new String[0], new String[0], new Object[0])) {
    TrackerDefaultInjector.insertBack(this, "com.guuidea.tracker.Server", "getSomeThings", new String[0], new String[0], "", tt, new Object[0]);
}
return (String[])((String[])tt);

}

isEnable方法的参数说明: 1.类名 2.方法名 3.参数名 4.group 5.参数值

insertFront参数说明: 1.当前对象 2.类名 3.方法名 4.参数名 5.group 6.tag值 7.参数值

insertBack方法和insertFront参数说明方法的区别是 insertBack在倒数第二参数多了一个返回值,该例子上就多了一个tt,如果该方法有返回值则返回结果,没有则返回null

五.关于获取属性对象

Command.instance().openGroup(group); //打开权限 只是打开权限 可以获取log Command.instance().addCommand("com.guuidea.tracker.Server.getSomeThings()", "before#getLog#"); //在方法执行之前获取log Command.instance().addCommand("com.guuidea.tracker.Server.getSomeThings()", "after#getResult#[{"name":"","key":1},{"name":"aa","key":2}]"); //在方法之后获取返回值的第一个元素,返回值本身是一个数组则name即空就可,该结果取的事返回值的第一个元素的aa属性的第二个元素 Command.instance().addCommand("com.guuidea.tracker.Server.getSomeThings(a,b)", "before#getArgs#0#[{"name":"","key":1}]"); //方法执行前的第0个参数的第一个元素 Command.instance().restoreCommand();

目前获取对象数据的方式有一下四种 public static final String GET_LOG = "getLog"; ////只支持在方法之前 即before#getLog //获取结果 public static final String GET_RESULT = "getResult"; //只支持方法之后 即after#getResult //方法的参数 public static final String GET_ARGS = "getArgs"; //方法前后都可以 //类的属性 public static final String GET_PROP = "getProp"; //方法前后都可以

6.关于配置规则 新增@InjectRule,它有一个isMainRule的属性,表示是否主rule,默认false就好

在app中新建一个类或者用在application上加一个注解如下: @InjectRule(regex = "^test+\w*", attrs = {Modifier.PUBLIC},isMainRule = true) public class MainApplication extends Application { } 这样表示匹配名字为test开头的方法名,且方法为PUBLIC属性,同时有效

除了主规则外,其他情况@InjectRule不可以单独使用,需配合@Tracker使用如下: @Tracker(injectRule = @InjectRule(regex = "onCreate")) public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { } }

regex:表示正则匹配 Modifier:目前支持的修饰符有 PUBLIC,PROTECTED,PRIVATE,ABSTRACT,STATIC,FINAL

如果同时存在主rule和当前rule,则以当前rule为准。

7.支持第匿名类(在正常类下的第一层匿名类),比如: 1.mTvAdd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); 则插装路径可能需要根据获取getClass()方法来判断真实路径

注意:匿名类的方法插装需要在父类的基础上添加注解,本身不支持注解

  1. 关于插装与否的判定,当前方法或类的颗粒度越小,权限越大,即 @Tracker(injectRule = @InjectRule(regex = "test")) private class SearchClass { @Tracker() public class KeyListener implements View.OnKeyListener { @Override public boolean onKey(View arg0, int arg1, KeyEvent arg2) { return false; } } }

这个例子中KeyListener的注解@Tracker优先级高于SearchClass的注解,所以onKey方法还是会被插装

10.添加了一些工具类在TrackerUtils中,以及一些callback类中添加两个默认定义的addListener和UploadListener的方法处理分别为 RocketChatCallBack、RocketChatCallBackWithOutToken和DefaultUploadListenerImpl、RockerChatUploaderImpl

添加混淆规则 -keep public class com.sdk.tracker.Trackers -keep public class com.sdk.tracker.log.TraceLog -keep public class com.sdk.annotation.{;} -keep public class com.sdk.tracker.listener.{;}