无痕埋点在Android中的实现
目标
- 解决手动打点效率低下问题
- 自动化埋点
本篇技术实现主要是运行是代理,不涉及到插桩技术,不引入插件,对业务影响点最小
技术难点
1. 如何拦截到所有的view的点击事件
view有个setAccessibilityDelegate方法可以通过自定义一个全局的AccessibilityDelegate对象来监听view的点击事件
object EventTrackerAccessibilityDelegate : View.AccessibilityDelegate() {
override fun sendAccessibilityEvent(host: View?, eventType: Int) {
super.sendAccessibilityEvent(host, eventType)
if (eventType == AccessibilityEvent.TYPE_VIEW_CLICKED) {
host?.let {
// 统一做埋点
}
}
}
}
通过给每个View设置上述单例对象,这样每当View被点击时,View.performClick内部就会触发上述方法。这样就能够拦截view的点击事件,而不用修改业务层代码。
2. 如何对app所有的view设置setAccessibilityDelegate
解决这个问题,就得拦截到app中view的创建。我们先要对Android中View的创建流程需要明白,对于android中的view创建,我们先从AppCompatActivity.onCreate方法入手
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
final AppCompatDelegate delegate = getDelegate();
delegate.installViewFactory(); //重点
delegate.onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
}
我们重点看installViewFactory方法,delegate返回的实际类型为AppCompatDelegateImpl,它继承了AppCompatDelegate抽象类
// AppCompatDelegateImpl.java
@Override
public void installViewFactory() {
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
if (layoutInflater.getFactory() == null) {
LayoutInflaterCompat.