andriod实现自己的ioc容器

时间:2022-11-03 10:15:20

1.需求

1.1实现自己的ioc容器,做到用注解方式为变量赋值,如下

@InjectView(R.id.text2)
private TextView testView;

2.实现

2.1定义注解接口,其实注解就是一个数据约束,定义注解前需要知道一些注解的基本知识

@target注解作用的目标
1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明


----------
@Retention保留时间的长短
1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)


----------

还有@document 和 @inherit 不怎么使用,自行查阅

package com.example.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface InjectView {

//返回R.id.view 的int值
public int value() default 0;

}

2.2实现使用注解为变量赋值 其实就是利用放射机制 一一赋值

package com.example.annotation;


public class InjectUtils {

public static void injectView(Activity activity)
{
//1.获得activity 的class
Class<? extends Activity> acClass = activity.getClass();
//2.获得所有字段 因为在一个activity中不止有一个view
Field[] acField = acClass.getDeclaredFields();

for(Field field:acField)
{
//获得view的注解
InjectView myView = field.getAnnotation(InjectView.class);
if(null!=myView)
{
//获得注解中的值
int value = myView.value();
//根据注解中的值实例view
View view = activity.findViewById(value);
try {
field.setAccessible(true);
field.set(activity,view);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}

}

}
}

2.3MainActivity,执行并赋值

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InjectUtils.injectView(this);
}

2.4其他,如为按钮使用注解添加单击事件也如此,不过比较复杂,需要代理。

相关文章