Android UI IoC注解加载布局

Android UI IoC注解加载布局

知识点:注解 反射

接下来一步步实现

1. 业务Activity 和 注解类ContentView
// 普通页面Activity代码,正常启动即可正常加载ioc_act.xml
@ContentView(R.layout.ioc_act)
public class IocAct extends BaseActivity {
}
// 该注解作用于类,接口或者枚举类型上
@Target(ElementType.TYPE)
// 注解会在class字节码文件中存在,jvm加载时可以通过反射获取到该注解的内容
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
    // int类型布局
    int value();
}
2. 业务ioc_act.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="注解加载布局" />
</RelativeLayout>
3. BaseActivity.java实现
public class BaseActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 帮助子类进行,布局、控件、事件的注入
        // 本篇先讲布局注入,后续控件,事件在补上
        InjectManager.inject(this);
    }
}
4. InjectManager实现
public class InjectManager {

    public static void inject(Activity act) {
        // 布局的注入
        injectLayout(act);
    }

    private static void injectLayout(Activity act) {
        Class<? extends Activity> clazz = act.getClass();
        // 获取类的注解
        ContentView contentView = clazz.getAnnotation(ContentView.class);
        if (contentView != null) {
            int layoutId = contentView.value();
            // 获取Activity指定方法
            try {
                Method method = clazz.getMethod("setContentView", int.class);
                method.invoke(act, layoutId);
                // 另一种写法:
                // act.setContentView(layoutId);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
    }
}

基于上述4步概括一下:

  1. 首先IocAct 继承 BaseActivity,BaseActivity在onCrate方法中通过InjectManager的inject方法代替完成了setContentView(R.layout.ioc_act)加载布局的操作
  2. InjectManager的inject方法首先获取IocAct的注解,继而获取注解值(R.layout.ioc_act),然后通过java反射获取Activity的setContentView方法调用,实现加载布局的任务

实际开发场景下,我们没必要这么去做,这么做目的是为了熟悉对注解,反射的使用

你可能感兴趣的:(Android,UI)