我來了我來了,今天給大家介紹一下數(shù)據(jù)埋點相關(guān)知識
首先數(shù)據(jù)埋點分為三種。
一 代碼埋點
這種是我接觸最多的埋點方式,直接進行代碼侵入埋點舉個例子
viewById.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
execute();
// Log.i(TAG, "after: " + System.currentTimeMillis() -beforTime);
}
});
logi這一行就屬于代碼埋點
優(yōu)點:靈活性高可以定制想要的屬性和字段
缺點:對代碼侵入,埋點必須熟悉業(yè)務的專業(yè)人員,工作量比較大,更新埋點通過發(fā)版來進行
二 全埋點
兩種實現(xiàn) 第一種hook系統(tǒng)方法,比如hook所有view的onclick事件 ,然后替換成自己的onclick事件。
舉個例子
public static void hookListener(Activity mActivity) {
if (null != mActivity) {
View view = mActivity.getWindow().getDecorView();
getView(view);
}
}
private static void getView(View view) {
if (view instanceof ViewGroup) {
for (int i = 0, count = ((ViewGroup) view).getChildCount(); i < count; i++) {
getView(((ViewGroup) view).getChildAt(i));
}
}
viewHook(view);
}
private static void viewHook(View view) {
try {
Class viewClass = Class.forName("android.view.View");
Field feild = viewClass.getDeclaredField("mListenerInfo");
feild.setAccessible(true);
Object mListenerInfo = feild.get(view);//view對象中的mListenerInfo實例
if (null != mListenerInfo) {
Class listenerInfo2 = Class.forName("android.view.View$ListenerInfo");//反射創(chuàng)建listenerinfo
Field mOnClickListener = listenerInfo2.getDeclaredField("mOnClickListener");
mOnClickListener.setAccessible(true);
View.OnClickListener lis = (View.OnClickListener) mOnClickListener.get(mListenerInfo);
if (lis != null) {
View.OnClickListener mOnClickListenerWrapper = new OnClickListenerWrapper(lis);
mOnClickListener.set(mListenerInfo,mOnClickListenerWrapper);//設(shè)置代理
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
這樣hook掉所有View的點擊事件,就可以監(jiān)聽到所有view的點擊事件了,缺點由于使用反射會消耗app的性能,影響運行速度。
第二種 aop方法,簡單解釋一下aop,java是面向?qū)ο缶幊?,aop面向切面編程,通俗的講它不關(guān)心對象,他關(guān)注的是某一個點,比如咱們方法中的單擊事件,這就是一個點,意思就是所有的單擊事件都是我的點,我是根據(jù)點來進行編程,只要是這個點就歸我管。
看一個例子
@Aspect
public class AspectJAnn {
private static final String TAG = "AspectJAnn";
@Before("execution(* android.view.View.OnClickListener.onClick(..))")
public void clickMethod(JoinPoint joinPoint) {
try {
Object[] args = joinPoint.getArgs();
for (int i = 0; i < args.length; i++) {
View pointView = (View) args[i];
String entryName = BaseApplication.getInstance().getResources().getResourceEntryName(pointView.getId());
if (pointView instanceof TextView){
entryName = ((TextView) pointView).getText().toString();
}
AnnHelper.get().onAnnClick(entryName, "no_from", ActivityCollector.getCurrentActivity().getClass().getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
寫了這個類,不用任何地方調(diào)用,我編譯之后,所有的onclick方法都會執(zhí)行到這里。(jar中包的除外,只能是我們自己寫的代碼,就是省去了我們自己寫)
原理:通過一個插件,在編譯時期(編譯時期是重點)把這個方法的調(diào)用自動插入到所有onclick方法中了,這也就是jar包中的單擊方法不能插入的原因??梢酝ㄟ^app反編譯后看到具體的實現(xiàn),我雖然看過但是忘記截圖了,這里就不上圖了
這種方案校對上一種方案的優(yōu)點,編譯時候加的代碼,不會影響運行性能,但是會影響編譯速度,不支持jar包,不支持喇嘛大表達式,而且導入包的時候我經(jīng)歷了各種莫名其妙絕望的錯誤,最后還好在各種朋友的幫助下完成了集成(朋友是我們一生的財富)。
附上一篇使用說明和github地址:使用說明,github地址
優(yōu)點:沒有代碼侵入,工作量很小
缺點:靈活性太差,拿不到特別想要的數(shù)據(jù)。
三 可視化埋點
簡單介紹,這種沒有太多用武之地,說完你就明白了。
類似全埋點的基礎(chǔ)上,根據(jù)后臺返回的具體坐標 比如距上下左右都是50dp的位置。這樣弊端 如果視圖修改就沒什么用了。也沒有遇到過這種埋點
參考 神策數(shù)據(jù) Android 埋點白皮書。