文章目录
总结
一、Android 布局依赖注入步骤
二、Android 布局依赖注入示例
1、创建依赖注入库
2、声明注解
3、Activity 基类
4、依赖注入工具类
5、客户端 Activity
总结
Android 依赖注入的核心就是通过反射获取 类 / 方法 / 字段 上的注解 , 以及注解属性 ; 在 Activity 基类中 , 获取该注解 以及 注解属性 , 进行相关操作 ;
一、Android 布局依赖注入步骤
正常控制 : Android 中加载布局操作 , 由自己的 Activity 类加载布局 ;
控制反转 : Android 中加载布局操作 , 由 第三者 加载 Activity 布局 ;
Android 布局依赖注入步骤 :
① 客户端 Activity : 定义 MainActivity , 继承 BaseActivity ;
② IOC 库中的 Activity 父类 : 定义 BaseActivity , 在 BaseActivity 中的 onCreate 方法中 , 处理依赖注入相关逻辑 ;
③ 依赖注入逻辑 : 获取 Activity 类 , 并使用反射获取类上的注解属性 ( 布局文件 ID ) , 为 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.TYPE) // 该注解作用于类上 @Retention(RetentionPolicy.RUNTIME) // 注解保留到运行时 public @interface ContentView { int value(); // 接收 int 类型值 }
@Target(ElementType.TYPE) 表示该注解作用与类上 ;
@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 { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 在此处注入布局 // 此处传入的 Activity 参数是 MainActivity 子类对象 InjectUtils.inject(this); } }
4、依赖注入工具类
package kim.hsl.ioc_lib; import android.app.Activity; public class InjectUtils { /** * 为 Activity 注入布局 * @param activity 该 Activity 是继承了 BaseActivity 的 MainActivity 实例对象 */ public static void inject(Activity activity) { // 获取 Class 字节码对象 Class<? extends Activity> clazz = activity.getClass(); // 反射获取类上的注解 ContentView contentView = clazz.getAnnotation(ContentView.class); // 获取注解中的布局 ID int layoutId = contentView.value(); // 为 Activity 设置显示的布局 activity.setContentView(layoutId); } }
5、客户端 Activity
package kim.hsl.ioc_demo; import kim.hsl.ioc_lib.BaseActivity; import kim.hsl.ioc_lib.ContentView; /** * 当该 MainActivity 启动时 , 调用 BaseActivity 的 onCreate 方法 * 在 BaseActivity 的 onCreate 方法中注入布局 */ @ContentView(R.layout.activity_main) public class MainActivity extends BaseActivity { }
运行结果 :