簡(jiǎn)單記錄下埋點(diǎn)幾種方案,詳情參考《Android全埋點(diǎn)解決方案》
采集信息
采集事件:頁面瀏覽事件/前后臺(tái)切換事件/點(diǎn)擊事件
設(shè)備id:
事件時(shí)間
屬性{
庫版本
app名稱
app版本
手機(jī)系統(tǒng):
手機(jī)廠商
手機(jī)型號(hào)
系統(tǒng)版本
屏幕寬度
屏幕高度
頁面全類名
頁面名稱
控件類型
控件id
控件名稱
}
頁面埋點(diǎn)
在application的onCreate中,注冊(cè)registerActivityLifecycleCallbacks
在onActivityResumed中提交頁面埋點(diǎn)信息谱秽。
多進(jìn)程前后臺(tái)埋點(diǎn)
跨進(jìn)程通信狀態(tài):
事件結(jié)束狀態(tài):切到后臺(tái)true,前臺(tái)false
切到后臺(tái)時(shí)間:onActivityPaused的時(shí)間
app啟動(dòng)uri
前臺(tái)
onActivityStarted->結(jié)束狀態(tài)為true->更新結(jié)束狀態(tài)為false->發(fā)送前臺(tái)事件
后臺(tái)
onActivityPaused->啟動(dòng)倒計(jì)時(shí),更新后臺(tái)時(shí)間
倒計(jì)時(shí)結(jié)束->發(fā)送后臺(tái)事件
onActivityStarted->
計(jì)算時(shí)差=當(dāng)前時(shí)間-切到后臺(tái)時(shí)間乒裆,
時(shí)差大于閾值并且結(jié)束狀態(tài)為false->發(fā)送后臺(tái)事件
取消倒計(jì)時(shí):
onActivityStarted->更新App啟動(dòng)uri為true
監(jiān)聽app啟動(dòng)uri變化->uri相等則取消倒計(jì)時(shí)
缺點(diǎn):
卸載會(huì)丟失后臺(tái)事件
事件埋點(diǎn)
代理View.OnClickListener
onActivityResumed->獲取到content->遍歷content->view有點(diǎn)擊事件->反射獲取view點(diǎn)擊事件,將原事件包裝季眷,將包裝事件設(shè)置到view
解決onResume之后動(dòng)態(tài)創(chuàng)建的View點(diǎn)擊事件:
onActivityResumed->獲取DecorView添加ViewTreeObserver.OnGlobalLayoutListener監(jiān)聽器秋茫,當(dāng)布局發(fā)生變化回調(diào)->走上面流程
onActivityStopped->移除監(jiān)聽器
缺點(diǎn):兼容性布疼,無法采集dialog等點(diǎn)擊事件
代理Window.Callback
當(dāng)用戶點(diǎn)擊某個(gè)控件時(shí)工猜,就會(huì)回調(diào)Window.Callback中的dispatchTouchEvent(MotionEvent event)方法米诉。
onActivityCreated->獲取Window.Callback->將callback進(jìn)行包裝->將包裝callback設(shè)置到window
處理事件:
遍歷decoreView->判斷view是否在點(diǎn)擊的坐標(biāo)內(nèi)->處理事件
缺點(diǎn):無法采集dialog等點(diǎn)擊事件,性能低,每次點(diǎn)擊時(shí),都需要去遍歷一次RootView
代理View.AccessibilityDelegate
view->performClick->sendAccessibibltyEvent
反射獲取view的AccessibilityDelegate->進(jìn)行包裝->回設(shè)給View
包裝AccessibilityDelegate->重寫sendAccessibibltyEvent->判斷事件狀態(tài)為點(diǎn)擊->處理
缺點(diǎn):輔助功能可能在部分rom會(huì)失效,反射效率低,無法采集dialog等點(diǎn)擊事件
透明層
onActivityCreated->將透明層(FrameLayout)添加到decoreView
透明層->監(jiān)聽onTouchEvent->down->獲取點(diǎn)擊坐標(biāo)范圍的子view->處理->
return super.onTouchEvent(event) 確保透明層不會(huì)阻斷事件
缺點(diǎn):無法采集dialog等點(diǎn)擊事件,性能低,每次點(diǎn)擊時(shí)篷帅,都需要去遍歷一次RootView
AspectJ
定義切面類->定義切點(diǎn)->方法增強(qiáng)@After 點(diǎn)擊事件->joinPoint.getArgs獲取到view->處理
缺點(diǎn):不支持lambda,無法織入第三方的庫,兼容性(D8史侣、Gradle 4.x)
ASM
1.定義Transform類(項(xiàng)目構(gòu)建階段,修改.class文件的一套標(biāo)準(zhǔn)API)拴泌,分別遍歷目錄和jar包進(jìn)行過濾
2.在visit方法獲取到class信息,visitMethod方法里獲取到method信息
3.判斷它所在的類實(shí)現(xiàn)了View.OnClickListener接口
4.在onMethodExit方法里進(jìn)行判斷,插入相關(guān)的代碼。
缺點(diǎn):目前無缺點(diǎn)
Javassist
·讀寫字節(jié)碼
和ASM類似
AST
自定義注解處理器->初始化獲取抽象語法樹->遍歷所有元素->如果類型為CLASS,獲取當(dāng)前元素的抽象語法樹->
自定義TreeTranslator處理每一個(gè)方法->如果方法包含onclick就插入代碼
缺點(diǎn):無法處理其他module,不支持lambda