Android之IOC框架介绍

最近看开源代码,发现有这么一句:

    @ViewInject(id = R.id.mIvGRZX,click = true)
    private ImageView mIvGRZX;

就来调查下相关的技术原理。

不用慌, 它就等同于: findViewById

IOC框架

Inversion of Control,英文缩写为IOC,字面翻译:控制反转。

就是一个类里面需要用到很多个成员变量,传统的写法,你要用这些成员变量,那么你就new 出来用呗!

IOC的原则是:NO,我们不要new,这样耦合度太高,你配置个xml文件,里面标明哪个类,里面用了哪些成员变量,等待加载这个类的时候,我帮你注入(new)进去;当然了,你又会觉得,写个配置文件,卧槽,这多麻烦。

于是乎,又出现了另一种方案,得你嫌配置文件麻烦,那用注解呗在你需要注入的成员变量上面加个注解,例如:@Inject,这样就行了,你总不能说这么个单词麻烦吧。当然了,有了配置文件和注解,那么怎么注入呢?其实就是把字符串类路径变成类么,这个时候需要用到反射。

反射不在多说,java代码比较普遍的技术。

注解

JAVA中的注解是一种继承自接口java.lang.annotation.Annotation的特殊接口。

简单来说就是JAVA通过动态代理的方式为你生成了一个实现了接口Annotation的实例,然后对该代理实例的属性赋值,这样就可以在程序运行时通过反射获取到注解的配置信息。

注解类似于一种标记,在程序中加了注解就等于为程序打上了某种标记。

程序可以利用JAVA的反射机制来了解你的类及各种元素上有无何种标记,针对不同的标记,就去做相应的事件。标记可以加在包,类,方法,方法的参数以及成员变量上。

Annotation

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。

Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。

Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。

创建注解类

添加代码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
    int value();
}

@Target表示注解可以用于什么地方,这里用于类,其他参数如:FILED(成员),METHOD(方法),PACKAGE(包),ANNOTATION_TYPE(注解的注解),CONSTRUCTOR(构造函数),PARAMETER(参数),LOCAL_VARIABLE(局部变更)

@Retention什么时候加载注解类,一般都是RetentionPolicy.RUNTIME运行的时候。

创建注入工具类

InjectUtils.class:

public class InjectUtils {
    public static final String ACTIVITY_MAIN_CONTENTVIEW="setContentView";

    /**
     * 注入所有
     * @param activity
     */
    public static void injectAll(Activity activity){
        injectContentView(activity);
    }

    /**
     * 注入ContentView
     * @param activity
     */
    public static void injectContentView(Activity activity){
        Class<? extends Activity> clazz = activity.getClass();//获取该类信息
        ContentView contentView = clazz.getAnnotation(ContentView.class);//获取该类ContentView的注解
        //如果有注解
        if(contentView!=null){
            int viewId=contentView.value();//获取注解类参数
            try {
                Method method=clazz.getMethod(ACTIVITY_MAIN_CONTENTVIEW,int.class);//获取该方法的信息
                method.setAccessible(true);//获取该方法的访问权限
                method.invoke(activity,viewId);//调用该方法的,并设置该方法参数
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

这样就关联起来了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章