XUtils之註解機制詳解

   各位小夥子們,這篇文章說一下xUtils裏面的註解原理。

      先來看一下xUtils裏面demo的代碼:

[java] view plain copy
  1. @ViewInject(R.id.tabhost)  
  2.     private FragmentTabHost mTabHost;  
  3. @ViewInject(R.id.big_img)  
  4.     private ImageView bigImage;  

       可能好多人一看就說這是個what,其實這是Java core裏面的內容,做JavaEE的應該很熟悉,像著名的spring框架就用了大量的註解。那到底什麼是註解呢?下面詳細講解一下Java註解:

       註解(Annotation) 爲我們在代碼中添加信息提供了一種形式化的方法,是我們可以在稍後某個時刻方便地使用這些數據(通過 解析註解 來使用這些數據),常見的作用有以下幾種:

  • 生成文檔。這是最常見的,也是java 最早提供的註解。常用的有@see @param @return 等
  • 跟蹤代碼依賴性,實現替代配置文件功能。比較常見的是spring 2.5 開始的基於註解配置。作用就是減少配置。現在的框架基本都使用了這種配置來減少配置文件的數量。也是
  • 在編譯時進行格式檢查。如@override 放在方法前,如果你這個方法並不是覆蓋了超類方法,則編譯時就能檢查出。

       包 java.lang.annotation 中包含所有定義自定義註解所需用到的原註解和接口。如接口java.lang.annotation.Annotation 是所有註解繼承的接口,並且是自動繼承,不需要定義時指定,類似於所有類都自動繼承Object。


      Java註解是附加在代碼中的一些元信息,用於一些工具在編譯、運行時進行解析和使用,起到說明、配置的功能。註解不會也不能影響代碼的實際邏輯,僅僅起到輔助性的作用。包含在 java.lang.annotation 包中。

Annotation類型裏面的參數該怎麼設定: 
   第一,只能用public或默認(default)這兩個訪問權修飾.例如,String value();這裏把方法設爲defaul默認類型. 
   第二,參數成員只能用基本類型byte,short,char,int,long,float,double,boolean八種基本數據類型和      String,Enum,Class,annotations等數據類型,以及這一些類型的數組.例如,String value();這裏的參數成員就爲String. 
   第三,如果只有一個參數成員,最好把參數名稱設爲"value",後加小括號.

1、元註解

     元註解是指註解的註解。包括  @Retention @Target @Document @Inherited四種。

1.1、@Retention: 定義註解的保留策略

    @Retention(RetentionPolicy.SOURCE)//註解僅存在於源碼中,在class字節碼文件中不包含
    @Retention(RetentionPolicy.CLASS)// 默認的保留策略,註解會在class字節碼文件中存在,但運行時無法得
    @Retention(RetentionPolicy.RUNTIME)// 註解會在class字節碼文件中存在,在運行時可以通過反射獲取到

1.2、@Target:定義註解的作用目標

其定義的源碼爲: 
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.ANNOTATION_TYPE)
     public @interface Target {
         ElementType[] value();
     }

    @Target(ElementType.TYPE)   //接口、類、枚舉、註解

    @Target(ElementType.FIELD) //字段、枚舉的常量
    @Target(ElementType.METHOD) //方法
    @Target(ElementType.PARAMETER) //方法參數
    @Target(ElementType.CONSTRUCTOR)  //構造函數
    @Target(ElementType.LOCAL_VARIABLE)//局部變量
    @Target(ElementType.ANNOTATION_TYPE)//註解
    @Target(ElementType.PACKAGE) ///包   
      其中的@interface是一個關鍵字,在設計annotations的時候必須把一個類型定義爲@interface,而不能用class或interface關鍵字,由以上的源碼可以知道,他的elementType 可以有多個,一個註解可以爲類的,方法的,字段的等等。

1.3、@Document:說明該註解將被包含在javadoc中
 
1.4、@Inherited:說明子類可以繼承父類中的該註解

2、java 註解的自定義

下面是自定義註解的一個例子

    @Retention(RetentionPolicy.RUNTIME)定義的這個註解是註解會在class字節碼文件中存在,在運行時可以通過反射獲取到。

    @Target({ElementType.TYPE,ElementType.METHOD})因此這個註解可以是類註解,也可以是方法的註解

這樣一個註解就自定義好了,當然註解裏面的成員可以爲基本的數據類型,也可以爲數據,Object等等

大概瞭解了一下Java註解機制,下面就說一說xUtils裏面用到的註解,以及思維流程:

[java] view plain copy
  1. package com.lidroid.xutils.view.annotation;  
  2.   
  3. import java.lang.annotation.ElementType;  
  4. import java.lang.annotation.Retention;  
  5. import java.lang.annotation.RetentionPolicy;  
  6. import java.lang.annotation.Target;  
  7.   
  8. @Target(ElementType.TYPE)  
  9. @Retention(RetentionPolicy.RUNTIME)  
  10. public @interface ContentView {  
  11.     int value();  
  12. }  
以上是ContentView的註解,一些聲明、參數。

[java] view plain copy
  1. private static void injectObject(Object handler, ViewFinder finder) {  
  2.   
  3.        Class<?> handlerType = handler.getClass();  
  4.   
  5.        // inject ContentView  
  6.        ContentView contentView = handlerType.getAnnotation(ContentView.class);  
  7.        if (contentView != null) {  
  8.            try {  
  9.                Method setContentViewMethod = handlerType.getMethod("setContentView"int.class);  
  10.                setContentViewMethod.invoke(handler, contentView.value());  
  11.            } catch (Throwable e) {  
  12.                LogUtils.e(e.getMessage(), e);  
  13.            }  
  14.        }}  

      以上是ViewUtils裏面的一個靜態註解對象函數,裏面用到了上面聲明的ContentView註解,getAnnotation是得到註解對象,handler是我們的activity傳進來的指針,通過指針得到Class類型(這個是類的類)的handlerType,handlerType通過getMethod動態加載setContentView,setContentView大家都很熟悉就是Android裏面的加載佈局的函數,然後得到一個Method進行反射機制,實現函數加載。

      setContentViewMethod.invoke(handler, contentView.value());這句話也可以這麼理解,那就是handler有setContentViewMethod這個方法,setContentViewMethod這個方法的參數是contentView.value()。

這樣就明白了爲什麼這樣

    @ContentView(R.layout.main)
     public class MyActivity extends FragmentActivity 就可以實現加載佈局的操作了,其他的xUtils的註解操作也是類似的。

下面是一個簡單流程圖:


如有問題請留言,轉載註明出處。http://blog.csdn.net/rain_butterfly/article/details/37931031

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