無痕打點github源碼html
1.前提
業務中常常須要對全部的打擊事件作統計, 最簡單的就是在每一個click處加上本身的代碼, 或者全繼承本身的view, 這些都跟業務耦合性過高,除了一些特殊的點,可能大部分點都是android
能夠用通用打點的方式來實現, 利用AOP 切面 將打點在編譯前從業務中剝離出去,甚至打點數據直接從服務器下發,或者直接經過gradle腳本動態讀取PM的打點文檔實現自動注入git
2.打點
一.通用點
通常是跟界面有關係的, 當前點處於哪一個activity, fragment, 這裏咱們能夠經過實現 通用的接口, 將界面通用點放入方法中,這個通常都能在基類中實現, 而後在AOP模塊中拿到對應數據,github
若是想徹底解耦,甚至能夠經過反射的方式拿到通用打點數據緩存
二.元素特殊點
好比咱們須要知道當前元素處於列表中的位置,或者當前元素的名稱,點擊時間之類服務器
這邊介紹的都是經過databinding 綁定的事件 ,由於比較通用,若是你界面裏用 setOnClickListener 的話能夠用aop切全局app
<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(),固然 直接取性能會比反射好gradle
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中,從而完成一次打點spa
後面具體經過什麼 方法忘平臺傳數據 能夠本身定義
具體能夠看頂部的源碼, 例子比較簡單,具體需求能夠按照這種思路擴展