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();
            }
        }
    }
}

這樣就關聯起來了。

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