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); // 获取注解中的布局 ID int 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; @Override protected 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}