【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取 Activity 中的所有方法 | 获取方法上的注解 | 获取注解上的注解 | 通过注解属性获取事件信息 )
文章目錄
- 前言
- 一、獲取 Activity 中的所有方法
- 二、獲取方法上的注解
- 三、獲取注解上的注解
- 四、通過(guò)注解屬性獲取相關(guān)事件信息
前言
Android 依賴(lài)注入的核心就是通過(guò)反射獲取 類(lèi) / 方法 / 字段 上的注解 , 以及注解屬性 ; 在 Activity 基類(lèi)中 , 獲取該注解 以及 注解屬性 , 進(jìn)行相關(guān)操作 ;
在博客 【IOC 控制反轉(zhuǎn)】Android 事件依賴(lài)注入 ( 事件三要素 | 修飾注解的注解 | 事件依賴(lài)注入步驟 ) 中 , 定義了 222 個(gè)注解 ,
- 第一個(gè)是方法上的注解 , 用于修飾方法 ;
- 第二個(gè)是修飾注解的注解 , 該注解用于配置注入的方法 ( 事件監(jiān)聽(tīng)方法 | 監(jiān)聽(tīng)器類(lèi)型 | 監(jiān)聽(tīng)器回調(diào)方法 ) ;
事件依賴(lài)注入比較復(fù)雜 , 涉及到動(dòng)態(tài)代理 , 本博客分析 【IOC 控制反轉(zhuǎn)】Android 事件依賴(lài)注入 ( 事件依賴(lài)注入代碼示例 ) 事件依賴(lài)注入的詳細(xì)步驟 ;
本博客的核心是 : 使用動(dòng)態(tài)代理 , 創(chuàng)建 View.OnClickListener 或 View.OnLongClickListener 或 View.onTouchListener 等接口的動(dòng)態(tài)代理類(lèi) ;
攔截相應(yīng)的 onClick , onLongClick , onTouch 方法 , 執(zhí)行自己的方法 , 其它方法正常執(zhí)行 ;
一、獲取 Activity 中的所有方法
通過(guò)反射獲取 Activity 類(lèi) , 然后調(diào)用 Class 的 getDeclaredMethods 方法 , 獲取 Activity 中的所有方法 ;
// 獲取 Class 字節(jié)碼對(duì)象 Class<? extends Activity> clazz = activity.getClass(); // 獲取所有方法 Method[] methods = clazz.getDeclaredMethods();二、獲取方法上的注解
獲取方法的所有注解 , 獲取的是 @OnClick({R.id.textView}) // 事件注入 注解 ;
調(diào)用 Method 方法的 getDeclaredAnnotations 方法 , 獲取方法上的注解數(shù)組 ;
// 循環(huán)遍歷類(lèi)的方法for (int i = 0; i < methods.length; i ++) {// 獲取方法的所有注解Annotation[] annotations = methods[i].getDeclaredAnnotations();}三、獲取注解上的注解
遍歷上個(gè)步驟獲取的注解數(shù)組 , 每個(gè)注解上可能有多個(gè)修飾注解的注解 , 如下注解是 OnClick 上的 333 個(gè)注解 ;
@Target(ElementType.METHOD) // 該注解作用于方法上 @Retention(RetentionPolicy.RUNTIME) // 注解保留到運(yùn)行時(shí) @EventBase(listenerSetter = "setOnClickListener",listenerType = View.OnClickListener.class,callbackMethod = "onClick") public @interface OnClick {int[] value(); // 接收 int 類(lèi)型數(shù)組 }調(diào)用 annotationType 方法 , 獲取注解的類(lèi)型 , 只處理 @EventBase 注解 ;
// 遍歷所有的注解for (int j = 0; j < annotations.length; j ++) {// 獲取注解類(lèi)型Class<? extends Annotation> annotationType = annotations[j].annotationType();// 獲取 @EventBase 注解EventBase eventBase = annotationType.getAnnotation(EventBase.class);if (eventBase == null) {// 如果沒(méi)有獲取到 EventBase 注解 , 執(zhí)行下一次循環(huán)continue;}}四、通過(guò)注解屬性獲取相關(guān)事件信息
最終目的是進(jìn)行如下設(shè)置 :
textView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {}});需要獲取 textView 組件 , 可以在注解中獲取 @OnClick({R.id.textView}) 組件 ID , 根據(jù) ID 獲取組件 ;
獲取并執(zhí)行 View 組件的 setOnClickListener 方法 , 通過(guò)反射獲取該方法 ;
創(chuàng)建 View.OnClickListener 接口實(shí)現(xiàn)類(lèi) , 并實(shí)現(xiàn) onClick 方法 , 這里特別注意 , 必須使用代理攔截該方法 , 替換成自己的方法 , 即在 MainActivity 中使用 @OnClick({R.id.textView}) 注解修飾的方法 ;
如果使用靜態(tài)代理 , 則只能創(chuàng)建固定的 View.OnClickListener 接口的靜態(tài)代理類(lèi) , 無(wú)法實(shí)現(xiàn)為組件設(shè)置長(zhǎng)按事件 , 觸摸事件 ;
因此這里使用動(dòng)態(tài)代理實(shí)現(xiàn) , 使用動(dòng)態(tài)代理 , 創(chuàng)建 View.OnClickListener 或 View.OnLongClickListener 或 View.onTouchListener 等接口的動(dòng)態(tài)代理類(lèi) ;
在 @EventBase 注解中配置事件的三要素 , 設(shè)置事件監(jiān)聽(tīng)的方法 , 監(jiān)聽(tīng)器類(lèi)型 , 事件觸發(fā)回調(diào)方法 ;
package kim.hsl.ioc_lib;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** 自定義注解* 用于注解上的注解* 用于依賴(lài)注入視圖*/ @Target(ElementType.ANNOTATION_TYPE) // 該注解作用于注解上 @Retention(RetentionPolicy.RUNTIME) // 注解保留到運(yùn)行時(shí) public @interface EventBase {/*** 設(shè)置事件監(jiān)聽(tīng)的方法* @return*/String listenerSetter();/*** 設(shè)置監(jiān)聽(tīng)器類(lèi)型* @return*/Class<?> listenerType();/*** 事件觸發(fā)后的回調(diào)方法* @return*/String callbackMethod(); }獲取注解中的事件三要素 :
// 點(diǎn)擊事件 View.setOnClickListenerString listenerSetter = eventBase.listenerSetter();// 監(jiān)聽(tīng)器類(lèi)型 View.OnClickListenerClass<?> listenerType = eventBase.listenerType();// 事件觸發(fā)回調(diào)方法 public void onClick(View v)String callbackMethod = eventBase.callbackMethod();獲取 要攔截的方法 以及 要注入的方法 ,
要攔截的方法是事件監(jiān)聽(tīng)器的方法 , 要注入的方法是用戶(hù)在 MainActivity 中使用 @OnClick 注解修飾的方法 ;
最后將這兩個(gè)方法放在 Map 集合中 ;
// 攔截 callbackMethod 方法 , 執(zhí)行 method[i] 方法// 這個(gè) method[i] 方法就是在 MainActivity 中用戶(hù)自定義方法// 被 OnClick 注解修飾的方法// 將其封裝到 Map 集合中Map<String, Method> methodMap = new HashMap<>();methodMap.put(callbackMethod, methods[i]);總結(jié)
以上是生活随笔為你收集整理的【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取 Activity 中的所有方法 | 获取方法上的注解 | 获取注解上的注解 | 通过注解属性获取事件信息 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【IOC 控制反转】Android 事件
- 下一篇: 【IOC 控制反转】Android 事件