android aop+databing实现侵入式点击 无痕打点

无痕打点github源码

1.前提

      业务中经常需要对所有的打击事件做统计, 最简单的就是在每个click处加上自己的代码, 或者全继承自己的view, 这些都跟业务耦合性太高,除了一些特殊的点,可能大部分点都是

可以用通用打点的方式来实现, 利用AOP 切面 将打点在编译前从业务中剥离出去,甚至打点数据直接从服务器下发,或者直接通过gradle脚本动态读取PM的打点文档实现自动注入

2.打点

 一.通用点

     一般是跟界面有关系的, 当前点处于哪个activity, fragment, 这里我们可以通过实现 通用的接口, 将界面通用点放入方法中,这个一般都能在基类中实现, 然后在AOP模块中拿到对应数据,

  如果想完全解耦,甚至可以通过反射的方式拿到通用打点数据

二.元素特殊点

  比如我们需要知道当前元素处于列表中的位置,或者当前元素的名称,点击时间之类

  这边介绍的都是通过databinding 绑定的事件 ,因为比较通用,如果你界面里用 setOnClickListener 的话可以用aop切全局

  

        <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
                  android:text="@{module.name}"
                  app:bindClickData='@{"name:" + module.name + ",position:" + position}'
                  android:textSize="20sp"
                  android:onClick="@{(view)->click.onMainClick(module,view)}"
                  android:padding="20dp"/>

  

app:bindClickData 是自定义的databind事件,这里 主要是为了传递一些item自有的参数,
这里可以看到我主要传了当前item的 名称 和在列表中的位置

public class BindAppUtils {
    @BindingAdapter("bindClickData")
    public static void bindClickData(View view, String data) {
        Log.e("lin","bindData="+data);
        view.setTag(R.id.snow_click_id,data);
    }
}

  这个就是自定义的绑定事件, 我们通过view.setTag 把特殊打点数据缓存到view中

android:onClick是view的普通点击事件,
databind所有click事件都会走generatedJava 目录下
你的包名.generated.callback.OnClickListener

    @Before("execution(* com.lin.aopdemo.generated.callback.OnClickListener.onClick(..))")
    public void onCommonClick(JoinPoint joinPoint) throws Throwable {
        View view  = (View)joinPoint.getArgs()[0];
        Log.e("lin","onClick="+joinPoint.getThis());
        if(view.getContext() instanceof ClickInter){
            ClickModel.INSTANCE.doClick(view,((ClickInter)view.getContext()).getPageParam());
        }
    }

  这里是切面方法,就是对应的点击view, 这里取了界面的通用参数, 如果要完全解耦,可以用反射获取getPageParam(),当然 直接取性能会比反射好

    fun doClick(view: View, m: Map<String,String>) {
        var data = view.getTag(R.id.snow_click_id) as String
        var map = mutableMapOf<String,String>()
        map.putAll(m);
        data?.split(",").forEach {
            if(it.contains(":")){
                map.put(it.split(":")[0],it.split(":")[1])
            }
        }
        Log.e("lin",map.toString())
    }

  具体的点击方法  我们通过view.getTag拿到前面 databing塞进去的特殊数据, 全部塞到一个map中,从而完成一次打点

    后面具体通过什么 方法忘平台传数据 可以自己定义

具体可以看顶部的源码, 例子比较简单,具体需求可以按照这种思路扩展

猜你喜欢

转载自www.cnblogs.com/dikeboy/p/10959918.html