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

首頁 > 系統 > Android > 正文

Android下hook點擊事件的示例

2019-12-12 00:33:09
字體:
來源:轉載
供稿:網友

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿拉善盟| 五峰| 花莲市| 安溪县| 云霄县| 清原| 大余县| 交口县| 唐海县| 静乐县| 富阳市| 涿鹿县| 马边| 甘孜| 营山县| 比如县| 进贤县| 右玉县| 日照市| 鄂尔多斯市| 沾益县| 德阳市| 双城市| 托克托县| 浦城县| 曲松县| 内乡县| 闸北区| 石台县| 偏关县| 海城市| 武陟县| 朔州市| 宁陕县| 平和县| 咸丰县| 奉化市| 蒲城县| 股票| 游戏| 龙南县|