hook 循环点击事件用哪个_Android下hook点击事件的示例

Hook是一种思想,也就是将原来的事件,替换到我们自己的事件,方便我们做一些切入处理。目的是不修改原来的代码,同时也避免遗漏的N多类里面处理。

最近需要在现有的app中设置统计埋点。去业务代码里埋的话似乎耦合度太高。所以决定使用hook的方法对事件进行埋点处理。

这里先记一下对点击事件hook的基本流程。

1.先建一个代理类实现View.OnClickListener,用来做点击后的后续处理。 import android.view.View;

/**

* 实现点击监听

*/

public class OnClickListenerProxy implements View.OnClickListener{

private View.OnClickListener mOriginalListener;

//直接在构造函数中传进来原来的OnClickListener

public OnClickListenerProxy(View.OnClickListener originalListener) {

mOriginalListener = originalListener;

}

@Override public void onClick(View v) {

if (mOriginalListener != null) {

mOriginalListener.onClick(v);

}

Log.d("LOGCAT","hooked!");

}

}

2.通过java的反射机制进行hook public static void hookOnClickListener(View view) {

try {

// 得到 View 的 ListenerInfo 对象

Method getListenerInfo = View.class.getDeclaredMethod("getListenerInfo");

//修改getListenerInfo为可访问(View中的getListenerInfo不是public)

getListenerInfo.setAccessible(true);

Object listenerInfo = getListenerInfo.invoke(view);

// 得到 原始的 OnClickListener 对象

Class> listenerInfoClz = Class.forName("android.view.View$ListenerInfo");

Field mOnClickListener = listenerInfoClz.getDeclaredField("mOnClickListener");

mOnClickListener.setAccessible(true);

View.OnClickListener originOnClickListener = (View.OnClickListener) mOnClickListener.get(listenerInfo);

// 用自定义的 OnClickListener 替换原始的 OnClickListener

View.OnClickListener hookedOnClickListener = new OnClickListenerProxy(originOnClickListener);

mOnClickListener.set(listenerInfo, hookedOnClickListener);

} catch (Exception e) {

Log.d("LOGCAT","hook clickListener failed!", e);

}

}

3.在你需要hook的事件后调用上面这个hookOnClickListener Button btnSend = (Button) findViewById(R.id.btn_send);

btnSend.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

log.info("onClick");

}

});

HookManager.hookOnClickListener(btnSend);

4.作为统计埋点,不免需要带点参数

在原业务代码的onClick里设置参数 private View.OnClickListener clickBtn = new Button.OnClickListener(){

@Override

public void onClick(View v) {

Map map = new HashMap();

map.put("name",v.getClass().getName());

v.setTag(v.getId(),map);

HookManager.hookOnClickListener(v);

}

};

在自定义的代理onClick里接收参数 @Override public void onClick(View v) {

if (mOriginalListener != null) {

mOriginalListener.onClick(v);

}

// Log.d("LOGCAT","hooked!"+v.getId());

//拿到之前传递的参数

Object obj = v.getTag(v.getId());

Log.d("LOGCAT","hooked!"+v.getId()+"_"+obj.toString());

}

至此就可以在hook里随意加入后续操作而不用改动原来的逻辑代码了。

相关github地址: https://github.com/codeqian/android-class-lib/tree/master/utilDemo/app/src/main/java/Hook

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持聚米学院。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值