全局监控 click事件的四种方式

本文介绍了全局监听click事件的四种方法:适配监听接口、反射代理、AccessibilityDelegate和分析dispatchTouchEvent。通过这些方法,可以实现全局防快速重复点击、通用打点分析和用户行为监控。其中,反射代理方式在不影响开发者的情况下实现最佳效果,而方式四的应用前景广泛,可获取所有手势的目标View。
摘要由CSDN通过智能技术生成

本文主要给大家分享如何在全局上去监听 click 点击事件,并做些通用处理或是拦截。使用场景可能就是具体的全局防快速重复点击,或是通用打点分析上报,用户行为监控等。以下将以四种不同的思路和实现方式去监控全局的点击操作,由简单到复杂逐一讲解。

方式一,适配监听接口,预留全局处理接口并作为所有监听器的基类使用

抽象出公共基类监听对象,可预留拦截机制和通用点击处理,简要代码如下:

public abstract class CustClickListener implements View.OnClickListener{
   
    @Override
    public void onClick(View view) {
        if(!interceptViewClick(view)){
            onViewClick(view);
        }
    }
    protected boolean interceptViewClick(View view){
        //TODO:这里可做一此通用的处理如打点,或拦截等。
        return false;
    }
    protected abstract void onViewClick(View view);
}

使用方式之一匿名对象作为公共监听器

CustClickListener mClickListener = new CustClickListener() {
    @Override
    protected void onViewClick(View view) {
        Toast.makeText(CustActvity.this, view.toString(), Toast.LENGTH_SHORT).show();
    }
};

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    findViewById(R.id.button).setOnClickListener(mClickListener);
}
这种方式比较简单,无兼容问题,但是需要自始至终都要使用基于基类的监听器对象,对开发者约束比较大。适用于新项目之初就有此使用约定。对于老代码重构工作量比较大,而且如果接入第三方墨盒模块就无能为力了。

方式二,反射代理,适时偷梁换柱开发者无感知,在适配包装器里做通用处理。

以下是代理接口和内置监听适配器,全局的监听接口需要实现IProxyClickListener并设置到内置适配器WrapClickListener

public interface IProxyClickListener {
   

    boolean onProxyClick(WrapClickListener wrap, View v);

    class WrapClickListener implements View.OnClickListener {

        IProxyClickListener mProxyListener;
        View.OnClickListener mBaseListener;

        public WrapClickListener(View.OnClickListener l, IProxyClickListener proxyListener) {
            mBaseListener = l;
            mProxyListener = proxyListener;
        }

        @Override
        public void onClick(View v) {
            boolean handled = mProxyListener == null ? false : mProxyListener.onProxyClick(WrapClickListener.this, v);
            if (!handled && mBaseListener != null) {
                mBaseListener.onClick(v);
            }
        }
    }
}

我们需要选择一个时机对所有设置有监听器的 View做监听代理的 hook .这个时机可以对 Activity 的根View添加一个视图变化监听(当然也可选择在 Activity 的 DOWN 事件的分发时机):

rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
     @Override
     public void onGlobalLayout() {
        hookViews(rootView, 0)      
     }
});
注:以上为了方便匿名注册了监听,实际使用在 Activity 退出时要反注册掉。

在进行代理前先要反射获取View监听器相关的 Method 和 Field 对象如下:

public void init() {
    if (sHookMethod == null) {
        try
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值