美文网首页Android开发
Android hook点击事件

Android hook点击事件

作者: 渐渐懂了吧 | 来源:发表于2021-06-25 14:30 被阅读0次
基本流程
  • 根据需求确定要hook的对象
  • 寻找要hook的对象的持有者,拿到要hook的对象
  • 定义要hook的对象的代理类,并且创建该类的对象
  • 使用上一步创建出来的对象,替换掉要hook的对象
示例代码

定义一个工具类用来hook

public class HookManager {
    
    @SuppressLint({"DiscouragedPrivateApi", "PrivateApi"})
    public static void hook(Context context, final View view) {
        try {
            //1.反射执行View类的getListenerInfo()方法,拿到View的ListenerInfo对象,这个对象就是点击事件的持有者
            Method method = View.class.getDeclaredMethod("getListenerInfo");
            method.setAccessible(true);//由于getListenerInfo()方法并不是public的,所以要加这个代码来保证访问权限
            Object listenerInfo = method.invoke(view);
            //2.取得真实的mOnClickListener对象
            Class<?> listenerInfoClz = Class.forName("android.view.View$ListenerInfo");//这是内部类的表示方法
            Field field = listenerInfoClz.getDeclaredField("mOnClickListener");
            final View.OnClickListener clickListener = (View.OnClickListener) field.get(listenerInfo);
            //3.创建我们自己的点击事件代理类
            //方式1:自己创建代理类
//            ProxyOnClickListener proxyOnClickListener = new ProxyOnClickListener(clickListener);
            //方式2:由于View.OnClickListener是一个接口,所以可以直接用动态代理模式
            //Proxy.newProxyInstance的3个参数依次分别是:
            //本地的类加载器
            //代理类的对象所继承的接口(用Class数组表示,支持多个接口)
            //代理类的实际逻辑,封装在new出来的InvocationHandler内
            Object proxyOnClickListener = Proxy.newProxyInstance(context.getClass().getClassLoader(), new Class[]{View.OnClickListener.class}, new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Log.e("yzt", "点击事件被hook到了");//加入自己的逻辑
                    return method.invoke(clickListener, args);//执行被代理的对象的逻辑
                }
            });
            //4.用我们自己的点击事件代理类,设置到"持有者"中
            field.set(listenerInfo, proxyOnClickListener);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //自定义代理类
    private static class ProxyOnClickListener implements View.OnClickListener {

        View.OnClickListener clickListener;

        public ProxyOnClickListener(View.OnClickListener clickListener) {
            this.clickListener = clickListener;
        }

        @Override
        public void onClick(View v) {
            Log.e("yzt", "点击事件被hook到了");//加入自己的逻辑
            if (clickListener != null) {
                clickListener.onClick(v);//执行被代理的对象的逻辑
            }
        }

    }

}

给对应的View设置点击事件,并hook这个View,这样就能在View被点击时加入自己的逻辑

        tv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("yzt", "点击事件");
            }
        });
        HookManager.hook(this, tv);

这里就通过打印信息来演示

2021-06-25 14:09:02.225 23154-23154/com.yzt.hookdemo E/yzt: 点击事件被hook到了
2021-06-25 14:09:02.225 23154-23154/com.yzt.hookdemo E/yzt: 点击事件

相关文章

网友评论

    本文标题:Android hook点击事件

    本文链接:https://www.haomeiwen.com/subject/iccoyltx.html