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