Android自动埋点的一种实现
博客专区 > fneg 的博客 > 博客详情
Android自动埋点的一种实现
fneg 发表于2年前
Android自动埋点的一种实现
  • 发表于 2年前
  • 阅读 1552
  • 收藏 4
  • 点赞 1
  • 评论 2

腾讯云 十分钟定制你的第一个小程序>>>   

摘要: Android自动埋点,通过配置文件埋点的一种实现

在App开发过程中,埋点都要花费很多时间,而且还有遗漏没有埋的情况,能不能做到服务器下发哪些控件要埋,然后客户端自动埋。 前几天想出来了一个方案,今天实现了一个Demo,大概过程就是:遍历界面上所有View --> 如果View设置了OnClickListener,并且View的ID在配置文件中,那就替换OnClickListener为DelegentOnClickListener -->DelegentOnClickListener先调用埋点,然后再调用原先View的ClickListener。 

1.首先获取到控件的OnClickListener,Android 系统中没有相对应的API,查看View的源码,发现可以通过反射的方式获取到,Android系统将View相关Listener放到了一个内部类ListenerInfo中,从View 的mListenerInfo中可以获取到OnClickListener,大概的代码是这样的:

private View.OnClickListener getOnClickListener(View view) {
    boolean hasOnClick = view.hasOnClickListeners();
    if (hasOnClick) {
        try {
            Method method = View.class.getDeclaredMethod("getListenerInfo", null);
            if (null != method) {
                method.setAccessible(true);
                Object object = method.invoke(view, new Object[]{});
                if (null != object) {
                    Class listenerInfoClazz = object.getClass();
                    Field mOnClickListener = listenerInfoClazz.getDeclaredField("mOnClickListener");
                    if (null != mOnClickListener) {
                        mOnClickListener.setAccessible(true);
                        Object listener = mOnClickListener.get(object);
                        if (null != listener && listener instanceof View.OnClickListener) {
                            return (View.OnClickListener) listener;
                        }
                    }
                }
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
    return null;
}

2.遍历界面中的所有View,然后替换在配置文件中的View的OnClickListener,实现代码:

private void setClickListener(final View view) {
    if (null != view) {
        boolean hasOnClick = view.hasOnClickListeners();
        if (hasOnClick) {
            final View.OnClickListener listener = getOnClickListener(view);
            int id = view.getId();
            String name = getResources().getResourceName(id);
            //AdapterView不能设置OnClickListener
            if (!(view instanceof AdapterView)) {
                //检查是否在配置文件中,请求OnClickListener没替换过
                if (!(listener instanceof DelegentOnClickListener) &&
                        mTraceManager.isNeedTrace(this.getClass().getName(), name)) {
                    view.setOnClickListener(new DelegentOnClickListener() {
                        @Override
                        public void onClick(View v) {
                            Log.e(TAG, "new clickListener");
                            if (null != listener) {
                                listener.onClick(v);
                            }
                            Log.e(TAG, v.getTag(v.getId()) + "");
                        }
                    });
                }
            }
        }
        if (view instanceof ViewGroup) {
            final ViewGroup viewGroup = (ViewGroup) view;
            int childCount = viewGroup.getChildCount();
            if (childCount > 0) {
                for (int i = 0; i < childCount; i++) {
                    View childView = viewGroup.getChildAt(i);
                    setClickListener(childView);
                }
            }
        }
    }

}

3.替换界面中所有的View的OnClickListener,实现代码: setClickListener(findViewById(android.R.id.content));

4.在Assets的配置文件中添加要追踪的Activity和View id。 这个Demo实现了大概的原理验证,距离真实的产品,还有很大的距离,包括替换所有View的OnClickListener的时机怎么选择,ListView,RecycleView的Item监听,还有OnTouchListenr,OnLongClickListener实现,通过设置DelegentTouchListener应该还可以实现界面的热力图,配置文件可以从服务器端下发,做到动态埋点,View可以有意识的setTag(id,object),然后埋点反序列化这个object,可以做到埋入一些参数信息,配置文件还可以扩展一下,有控件名称之类的。 配图很梦幻,如果实现了自动埋点,对运营和开发来说也是梦幻的。  

项目地址:https://github.com/fengcunhan/AutoTrace 


共有 人打赏支持
fneg
粉丝 76
博文 39
码字总数 22636
评论 (2)
PREPOET
https://github.com/mixpanel/mixpanel-android 有开源的埋点SDK,利用setAccessibilityDelegate
本人慧星撞地球

引用来自“PREPOET”的评论

https://github.com/mixpanel/mixpanel-android 有开源的埋点SDK,利用setAccessibilityDelegate

回复@PREPOET : 大哥这东西怎么用啊,能拿过来直接用吗?等待您的答复
×
fneg
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: