国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android下hook點(diǎn)擊事件的示例

2019-10-21 21:39:52
字體:
供稿:網(wǎng)友

Hook是一種思想,也就是將原來的事件,替換到我們自己的事件,方便我們做一些切入處理。目的是不修改原來的代碼,同時(shí)也避免遺漏的N多類里面處理。

最近需要在現(xiàn)有的app中設(shè)置統(tǒng)計(jì)埋點(diǎn)。去業(yè)務(wù)代碼里埋的話似乎耦合度太高。所以決定使用hook的方法對(duì)事件進(jìn)行埋點(diǎn)處理。

這里先記一下對(duì)點(diǎn)擊事件hook的基本流程。

1.先建一個(gè)代理類實(shí)現(xiàn)View.OnClickListener,用來做點(diǎn)擊后的后續(xù)處理。

import android.view.View;/** * 實(shí)現(xiàn)點(diǎn)擊監(jiān)聽 */public class OnClickListenerProxy implements View.OnClickListener{  private View.OnClickListener mOriginalListener;  //直接在構(gòu)造函數(shù)中傳進(jìn)來原來的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的反射機(jī)制進(jìn)行hook

public static void hookOnClickListener(View view) {    try {      // 得到 View 的 ListenerInfo 對(duì)象      Method getListenerInfo = View.class.getDeclaredMethod("getListenerInfo");      //修改getListenerInfo為可訪問(View中的getListenerInfo不是public)      getListenerInfo.setAccessible(true);      Object listenerInfo = getListenerInfo.invoke(view);      // 得到 原始的 OnClickListener 對(duì)象      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的事件后調(diào)用上面這個(gè)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.作為統(tǒng)計(jì)埋點(diǎn),不免需要帶點(diǎn)參數(shù)

在原業(yè)務(wù)代碼的onClick里設(shè)置參數(shù)

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里接收參數(shù)

@Override public void onClick(View v) {    if (mOriginalListener != null) {      mOriginalListener.onClick(v);    }//    Log.d("LOGCAT","hooked!"+v.getId());    //拿到之前傳遞的參數(shù)    Object obj = v.getTag(v.getId());    Log.d("LOGCAT","hooked!"+v.getId()+"_"+obj.toString());  }

至此就可以在hook里隨意加入后續(xù)操作而不用改動(dòng)原來的邏輯代碼了。

相關(guān)github地址: https://github.com/codeqian/android-class-lib/tree/master/utilDemo/app/src/main/java/Hook

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到Android開發(fā)頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 龙门县| 克拉玛依市| 萨嘎县| 中宁县| 永登县| 措勤县| 阜宁县| 敦煌市| 琼海市| 长白| 达州市| 白水县| 什邡市| 龙游县| 平邑县| 信丰县| 余干县| 师宗县| 浦东新区| 梅河口市| 福州市| 屏南县| 大方县| 新营市| 永州市| 中阳县| 洪雅县| 六盘水市| 浑源县| 正定县| 民乐县| 永胜县| 永顺县| 梧州市| 吉安县| 广宁县| 海南省| 南江县| 台江县| 潜江市| 岱山县|