日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 创建 事件监听器 对应的 动态代理 | 动态代理的数据准备 | 创建调用处理程序 | 创建动态代理实例对象 )

發布時間:2025/6/17 Android 31 豆豆

文章目錄

  • 前言
  • 一、創建 事件監聽器 對應的 動態代理
  • 二、動態代理 數據準備
  • 三、動態代理 調用處理程序
  • 四、動態代理 實例對象創建

前言

Android 依賴注入的核心就是通過反射獲取 類 / 方法 / 字段 上的注解 , 以及注解屬性 ; 在 Activity 基類中 , 獲取該注解 以及 注解屬性 , 進行相關操作 ;

在博客 【IOC 控制反轉】Android 事件依賴注入 ( 事件三要素 | 修飾注解的注解 | 事件依賴注入步驟 ) 中 , 定義了 222 個注解 ,

  • 第一個是方法上的注解 , 用于修飾方法 ;
  • 第二個是修飾注解的注解 , 該注解用于配置注入的方法 ( 事件監聽方法 | 監聽器類型 | 監聽器回調方法 ) ;

事件依賴注入比較復雜 , 涉及到動態代理 , 本博客分析 【IOC 控制反轉】Android 事件依賴注入 ( 事件依賴注入代碼示例 ) 事件依賴注入的詳細步驟 ;


本博客的核心是 : 使用動態代理 , 創建 View.OnClickListener 或 View.OnLongClickListener 或 View.onTouchListener 等接口的動態代理類 ;
攔截相應的 onClick , onLongClick , onTouch 方法 , 執行自己的方法 , 其它方法正常執行 ;





一、創建 事件監聽器 對應的 動態代理



為組件設置的監聽器可能是 View.OnClickListener 或 View.OnLongClickListener 或 View.onTouchListener 等監聽器 , 因此使用 靜態代理 , 需要為每個監聽器都要設置一個單獨的類 , 比較繁瑣 ;

這里使用動態代理實現上述功能 ;

動態代理是作用于接口上的 , 根據接口動態創建該接口子類的代理對象 ;

原來是設置了一個匿名內部類 , 這個匿名內部類就是代理模式中的 被代理對象 ;

textView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {}});

現在使用 動態代理 , 創建一個 代理對象 , 代理 上述 匿名內部類 被代理對象 , 要在調用 onClick 方法時 , 注入自己的業務邏輯 ;


該動態代理中的元素梳理 :

  • 目標對象 ( 主題對象 ) : View.OnClickListener 接口 ;
  • 被代理對象 : View.OnClickListener 接口匿名內部類 ;
new View.OnClickListener() {@Overridepublic void onClick(View v) {}}
  • 代理對象 : 使用 Proxy.newProxyInstance 方法 , 由 JVM 自動生成字節碼類 就是代理對象 , 之后返回一個代理對象 的實例對象 ;
  • 客戶端 : 框架開發者開發的 依賴注入 工具類 , 在該工具類中執行動態代理的調用操作 ;




二、動態代理 數據準備



執行動態代理前 , 首先要知道攔截接口方法 , 以及要注入的方法 ;

攔截到接口方法后 , 替換成自己注入的方法 , 就是調用自己的方法 ;

將二者封裝到 Map 集合中 , 方便在攔截后 , 調用 Map 的 get 方法 , 查看是否有要注入的方法 ;

// 攔截 callbackMethod 方法 , 執行 method[i] 方法// 這個 method[i] 方法就是在 MainActivity 中用戶自定義方法// 被 OnClick 注解修飾的方法// 將其封裝到 Map 集合中Map<String, Method> methodMap = new HashMap<>();methodMap.put(callbackMethod, methods[i]);



三、動態代理 調用處理程序



在該動態代理中 , 首先要注入 Activity 和 上面準備的 Map 集合 , Map 集合中封裝了 要攔截的接口方法 和 要注入的方法 ;


首先獲取被代理接口中的 回調的方法名稱, 該方法是 onClick 或者 onLongClick 或者 onTouch 等方法 ;

Method 方法在參數中有 , 直接調用 Method method 參數的 getName() 方法獲取接口名稱 ;

// 獲取回調的方法名稱, 該方法是 onClick 或者 onLongClick 或者 onTouch 等方法String name = method.getName();

然后到 Map 集合中查找 , 是否要攔截該 接口方法 , 如果要攔截 , 肯定能從 Map 集合中獲取到要注入的方法 , 如果不需要攔截 , 獲取的結果是 null ;

// 獲取對應的被調用方法Method method1 = methodMap.get(name);

如果被調用的方法 需要被攔截 , 則能獲取到被攔截后替換的方法 , 執行該注入的方法即可 ;

// 如果被調用的方法 需要被攔截 , 則能獲取到被攔截后替換的方法if (method1 != null) {// 執行用戶 Activity 中的相應方法return method1.invoke(activity, args);}

如果不攔截該方法 , 則獲取的注入方法為 null , 直接返回該方法 , 注意調用 method.invoke(proxy, args) , 正常執行該接口方法即可 ;

// 其它方法正常執行return method.invoke(proxy, args);

代碼示例 :

package kim.hsl.ioc_lib;import android.app.Activity;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Map;public class EventInvocationHandler implements InvocationHandler {/*** 客戶端 Activity*/private Activity activity;/*** 攔截 callbackMethod 方法 , 執行 method[i] 方法* 這個 method[i] 方法就是在 MainActivity 中用戶自定義方法* 被 OnClick 注解修飾的方法* 將其封裝到 Map 集合中*/private Map<String, Method> methodMap;public EventInvocationHandler(Activity activity, Map<String, Method> methodMap) {this.activity = activity;this.methodMap = methodMap;}/*** 攔截方法 , 并使用自己的方法替換* 如 : 發現是 onClick 方法 , 則替換成用戶自定義的方法 (被 @OnClick 注解修飾的方法)* @param proxy* @param method* @param args* @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 獲取回調的方法名稱, 該方法是 onClick 或者 onLongClick 或者 onTouch 等方法String name = method.getName();// 獲取對應的被調用方法Method method1 = methodMap.get(name);// 如果被調用的方法 需要被攔截 , 則能獲取到被攔截后替換的方法if (method1 != null) {// 執行用戶 Activity 中的相應方法return method1.invoke(activity, args);}// 其它方法正常執行return method.invoke(proxy, args);} }



四、動態代理 實例對象創建



調用 Proxy.newProxyInstance 方法 , 創建動態代理的 實例對象 , 傳入到代理的接口數組 , 這個接口數組元素可以是 View.OnClickListener.class 或 View.OnLongClickListener.class 或 View.OnTouchListener.class 等字節碼類 ;

在調用處理程序中 , 攔截上述接口中的方法 , 并替換成自己的方法 , 也就是用戶在 MainActivity 中使用 @OnClick 注解修飾的方法 ;

// 獲取監聽器 View.OnClickListener 接口的代理對象EventInvocationHandler eventInvocationHandler =new EventInvocationHandler(activity, methodMap);Object proxy = Proxy.newProxyInstance(listenerType.getClassLoader(), // 類加載器new Class<?>[]{listenerType}, // 接口數組eventInvocationHandler); // 調用處理程序

該動態代理實例對象創建后 , 將其當做 View.OnClickListener.class 或 View.OnLongClickListener.class 或 View.OnTouchListener.class 等字節碼類的實例對象使用即可 ;

總結

以上是生活随笔為你收集整理的【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 创建 事件监听器 对应的 动态代理 | 动态代理的数据准备 | 创建调用处理程序 | 创建动态代理实例对象 )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产一级av毛片 | 老司机深夜福利在线观看 | 日噜噜夜噜噜 | av在线黄 | 色图自拍偷拍 | 少妇又紧又色又爽又刺激视频 | 最新免费av网站 | 97自拍网 | 国产亚洲精品精品精品 | 亚洲大片免费观看 | 在线观看精品一区 | 国产性猛交xxxx免费看久久 | 日韩欧美视频在线免费观看 | 日韩阿v| 久久91亚洲人成电影网站 | 亚洲av成人无码久久精品老人 | 免费69视频| 日本123区 | 久久夜色精品国产欧美乱极品 | 四虎com| 一区二区自拍偷拍 | 日日操操 | www欧美| 男男黄色片 | 欧美大片一区二区 | 福利一二三区 | 色片在线免费观看 | 亚洲色成人www永久在线观看 | 污片在线免费看 | 青青草视频在线观看 | 免费日韩 | 久久国产精品系列 | 九色婷婷 | 公妇借种乱htp109cc | 日韩经典一区二区 | 久久精品国产露脸对白 | 亚洲精品乱码久久久久久久久久久久 | 婷婷久久综合 | 日本高清不卡视频 | 看特级黄色片 | 欧美成人免费看 | 女人黄色片 | 三级影片在线播放 | 成人做爰的视频 | 人人看人人干 | 国产精品二区在线 | 国产精品乱码久久久久久久久 | 亚洲精品色午夜无码专区日韩 | 黄频在线 | 肉嫁高柳家 高清 | 黄视频在线免费看 | 欧美色亚洲色 | 久久这里只有精品国产 | 久久久久久9| 欧美日韩国产精品一区二区三区 | 男女操操视频 | 天天插天天狠天天透 | 国产另类自拍 | 一区二区在线不卡 | 男生尿隔着内裤呲出来视频 | 黄色片女人 | 中字幕视频在线永久在线观看免费 | 国模在线视频 | 亚洲精品天堂成人片av在线播放 | 视频一区二区三区在线观看 | 在线成人毛片 | 天天色网站 | 精品久久免费观看 | 私人av | 人人免费操 | 中文字幕在线视频精品 | 爱爱小视频免费看 | 黄a免费网络 | 又爽又黄又无遮挡 | 精品人妻一区二区三区蜜桃 | 免费精品无码AV片在线观看黄 | 香蕉久久夜色精品 | 性chinese天美传媒麻 | 国产粉嫩白浆 | 337p日本欧洲亚洲鲁鲁 | 日韩福利在线观看 | 免费黄色一级 | 日本一区二区精品 | 精品视频免费观看 | 在线观看麻豆av | 国产精品久久久爽爽爽麻豆色哟哟 | 91精彩刺激对白 | 日本三级小视频 | 久久久久久国产精品三区 | 国产成人资源 | 综合一区 | 91久久久久久久久久 | 人妻视频一区二区 | 操批网站 | 91久久精品在线 | 国产精品秘入口18禁麻豆免会员 | 97夜夜操| 亚洲婷婷在线观看 | 严厉高冷老师动漫播放 |