文章目录

  • 总结
  • 一、Android 视图依赖注入步骤
  • 二、Android 布局依赖注入示例
    • 1、创建依赖注入库
    • 2、声明注解
    • 3、Activity 基类
    • 4、依赖注入工具类
    • 5、客户端 Activity
  • 三、博客源码

总结

Android 依赖注入的核心就是通过反射获取 类 / 方法 / 字段 上的注解 , 以及注解属性 ; 在 Activity 基类中 , 获取该注解 以及 注解属性 , 进行相关操作 ;

一、Android 视图依赖注入步骤


Android 视图依赖注入步骤 :

  • ① 声明注解 : 声明视图注入注解 BindBiew ;
  • ② 客户端 Activity : 定义 MainActivity , 继承 BaseActivity , 在属性字段上使用 @BindBiew 注解注入视图 ;
  • ③ IOC 库中的 Activity 父类 : 定义 BaseActivity , 在 BaseActivity 中的 onCreate 方法中 , 处理依赖注入相关逻辑 ;
  • ④ 依赖注入逻辑 : 获取 Activity 类 , 并使用反射获取类中的所有属性字段 , 获取所有的 @BindBiew 注解 , 如果找到该注解 , 执行 findViewById 获取视图组件对象 , 并赋值给 Activity 中的属性字段 ;

二、Android 布局依赖注入示例


1、创建依赖注入库

首先在 Android 应用中 , 创建一个 " Android Library " ,

设置主应用依赖该 Android 依赖库 :

dependencies {implementation project(path: ':ioc_lib')
}

2、声明注解

创建如下注解 :

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.FIELD)   // 该注解作用于字段上
@Retention(RetentionPolicy.RUNTIME)    // 注解保留到运行时
public @interface BindView {int value();    // 接收 int 类型值
}

@Target(ElementType.FIELD) 表示该注解作用于属性字段上 ;

@Retention(RetentionPolicy.SOURCE) 注解保留到源码期 , Java 源码时期 RetentionPolicy.SOURCE -> Class 字节码时期 RetentionPolicy.CLASS -> JVM 运行时时期 RetentionPolicy.RUNTIME ;

int value() 表示该注解接收一个 int 类型的值 ;

3、Activity 基类

package kim.hsl.ioc_lib;import android.app.Activity;
import android.os.Bundle;import androidx.annotation.Nullable;public class BaseActivity extends Activity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 在此处注入布局//      此处传入的 Activity 参数是 MainActivity 子类对象InjectUtils.inject(this);}
}

4、依赖注入工具类

将上一篇博客 【IOC 控制反转】Android 布局依赖注入 ( 布局依赖注入步骤 | 布局依赖注入代码示例 ) 中的布局注入 , 抽到 injectLayout 方法中 ; 将注入视图组件定义在 injectViews 方法中 ;

package kim.hsl.ioc_lib;import android.app.Activity;
import android.view.View;import java.lang.reflect.Field;public class InjectUtils {/*** 为 Activity 注入布局* @param activity  该 Activity 是继承了 BaseActivity 的 MainActivity 实例对象*/public static void inject(Activity activity) {// 注入布局文件injectLayout(activity);// 注入视图组件injectViews(activity);}/*** 注入布局文件*/private static void injectLayout(Activity activity) {// 获取 Class 字节码对象Class<? extends Activity> clazz = activity.getClass();// 反射获取类上的注解ContentView contentView = clazz.getAnnotation(ContentView.class);// 获取注解中的布局 IDint layoutId = contentView.value();// 为 Activity 设置显示的布局activity.setContentView(layoutId);}/*** 注入视图组件*/private static void injectViews(Activity activity) {// 获取 Class 字节码对象Class<? extends Activity> clazz = activity.getClass();// 获取类的属性字段Field[] fields = clazz.getDeclaredFields();// 循环遍历类的属性字段for (int i = 0; i < fields.length; i ++) {// 获取字段Field field = fields[i];// 属性有可能是私有的, 这里设置可访问性field.setAccessible(true);// 获取字段上的注解, @BindView 注解//  注意不是所有的属性字段都有 @BindView 注解BindView bindView = field.getAnnotation(BindView.class);if (bindView == null) {// 如果没有获取到 BindView 注解 , 执行下一次循环continue;}// 获取注入的视图组件int viewId = bindView.value();// 根据组件 id 获取对应组件对象View view = activity.findViewById(viewId);try {// 通过反射设置 Activity 的对应属性字段的值field.set(activity, view);} catch (IllegalAccessException e) {e.printStackTrace();}}}
}

5、客户端 Activity

package kim.hsl.ioc_demo;import android.util.Log;
import android.widget.TextView;import kim.hsl.ioc_lib.BaseActivity;
import kim.hsl.ioc_lib.BindView;
import kim.hsl.ioc_lib.ContentView;/*** 当该 MainActivity 启动时 , 调用 BaseActivity 的 onCreate 方法*      在 BaseActivity 的 onCreate 方法中注入布局*/
@ContentView(R.layout.activity_main)    // 布局注入
public class MainActivity extends BaseActivity {/*** 视图注入*/@BindView(R.id.textView)private TextView textView;@Overrideprotected void onResume() {super.onResume();// 验证 textView 是否注入成功Log.i("MainActivity", "textView : " + textView);}
}

运行结果 :

Logcat 打印结果 :

I/MainActivity: textView : android.widget.TextView{fe85f76 V.ED..... ......ID 0,0-0,0 #7f08017e app:id/textView}

三、博客源码


GitHub : https://github.com/han1202012/IOC_Demo

CSDN : https://download.csdn.net/download/han1202012/24031128

【IOC 控制反转】Android 视图依赖注入 ( 视图依赖注入步骤 | 视图依赖注入代码示例 )相关推荐

  1. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取要注入事件的 View 对象 | 通过反射获取 View 组件的事件设置方法 )

    文章目录 前言 一.获取要注入事件的 View 对象 二.通过反射获取 View 组件的事件设置方法并执行 前言 Android 依赖注入的核心就是通过反射获取 类 / 方法 / 字段 上的注解 , ...

  2. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取 Activity 中的所有方法 | 获取方法上的注解 | 获取注解上的注解 | 通过注解属性获取事件信息 )

    文章目录 前言 一.获取 Activity 中的所有方法 二.获取方法上的注解 三.获取注解上的注解 四.通过注解属性获取相关事件信息 前言 Android 依赖注入的核心就是通过反射获取 类 / 方 ...

  3. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入代码示例 )

    文章目录 总结 一.Android 事件依赖注入示例 1.创建依赖注入库 2.声明注解 (1).修饰注解的注解 (2).修饰方法的注解 3.Activity 基类 4.动态代理类调用处理程序 5.依赖 ...

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

    文章目录 前言 一.创建 事件监听器 对应的 动态代理 二.动态代理 数据准备 三.动态代理 调用处理程序 四.动态代理 实例对象创建 前言 Android 依赖注入的核心就是通过反射获取 类 / 方 ...

  5. 【IOC 控制反转】Android 布局依赖注入 ( 布局依赖注入步骤 | 布局依赖注入代码示例 )

    文章目录 总结 一.Android 布局依赖注入步骤 二.Android 布局依赖注入示例 1.创建依赖注入库 2.声明注解 3.Activity 基类 4.依赖注入工具类 5.客户端 Activit ...

  6. IOC控制反转(依赖注入思想)

    IOC控制反转(依赖注入思想) 获取map 类型的 request session application 的方法: 实现RequestAware,SessionAware,ApplicationAw ...

  7. 【Java从0到架构师】Spring - IoC 控制反转、DI 依赖注入

    IoC 控制反转.DI 依赖注入 Spring 简介 Spring 基本使用 - IoC 容器 依赖注入 (Dependency Injection) 基于 setter 的注入 - 自定义对象 be ...

  8. 什么是IOC(控制反转)、DI(依赖注入)举个形象的例子通俗易懂

    更多免费教学文章请关注这里 学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清 ...

  9. Spring-初识Spring框架-IOC控制反转(DI依赖注入)

    ---恢复内容开始--- IOC :控制反转 (DI:依赖注入) 使用ioc模式开发 实体类必须有无参构造方法 1.搭建Spring环境 下载jar http://maven.springframew ...

最新文章

  1. LightTools( 32-64) 8.4.0下载与安装方法,lighttools免费版,lighttools(光学建模软件)【亲测有效】
  2. 三个线程按循序一个打印A一个打印B一个打印C 循环打印?
  3. union 中的注意事项
  4. dede后台title怎么修改的?去掉XXXX-织梦内容管理系统V5.7
  5. python颜色识别原理_电脑控制手机 Python实现颜色识别功能
  6. Docker进阶-快速扩容
  7. 文件包含常见绕过方法
  8. 基于Redis的分布式锁的简单实现
  9. idea中Gsonformat插件工具使用
  10. 用java实现学生成绩管理系统(附有详细代码)
  11. 康佳电视软件测试工程师,康佳电视怎么样之康佳55吋曲面人工智能电视试用测评...
  12. latex插图编号_LaTex技巧[26]:Latex重新为图片编号
  13. 深度学习图片分类实战学习
  14. 使用comm在java程序中管理本地端口[回钦波:高级软件工程师]
  15. 6park留园 android,‎「掌上留园-6park」をApp Storeで
  16. TCP/UDP 区别
  17. 《Attention Is All Y ou Need》翻译 Ashish Vaswani Noam Shazeer Niki Parmar Jakob etc.
  18. 【SLAM文献】2017-2018 CVPR ICCV ECCV 相机位姿估计、视觉定位、SLAM相关论文综述
  19. bash参考手册之三(基本的Shell特性)续二
  20. Java Static 变量初始化

热门文章

  1. wpservice.exe应用程序错误
  2. 九维 Addon for SBO 功能说明及新版软件下载
  3. 2018.12.22 spoj7258 Lexicographical Substring Search(后缀自动机)
  4. g711u与g729比较编码格式
  5. 20165237 2017-2018-2 《Java程序设计》第5周学习总结
  6. details和summary标签
  7. Specify compute hosts with SSDs
  8. 《JavaScript高级程序设计 第3版》-学习笔记-1
  9. Husband的忏悔书(IT攻城狮)
  10. Spring.NET性能