美文网首页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