Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Annotation注解的剖析和使用

Android Annotation注解的剖析和使用

編輯:關於Android編程

都說Annotation的運用非常簡單,但真正我們需要下手實現的的時候,有的時候就不知道從哪裡下手,為什麼我們覺得很簡單的東西,但卻無法下手呢?
原因只有一個,我們對它的使用非常少,但對於寫框架的人來說Annotation卻使用的頻率非常高。那既然我們平時用的非常少,我寫這篇blog就沒什麼意義了,的確,那我也只當是給大家做個查閱的文檔。不過我還是希望大家能通過這篇blog,加強對Annotation的理解,這篇blog省去了Annotation不必要的知識點,就像慕課網所說的只學有用的。
進入主題:
一、先分析源碼:
只需要知道一下四個類就行了
1、

  @Documented
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.ANNOTATION_TYPE)
  public @interface Retention {
      RetentionPolicy value();
  }

這個注解的作用是當我們需要聲明自定義的Annotation是,需要用到此注解,還需要設置value的值;value的值的作用,就需要講第二個類的時候說明,使用方法,可以參考此類本身,直接在自定義的Annotation上加上@Retention(RetentionPolicy.RUNTIME),或者另一種寫法@Retention(value = RetentionPolicy.RUNTIME),效果是一樣的,這裡需要注意一點的是,Annotation可以用自己來對自己進行注解說明。
2、

  public enum RetentionPolicy {
      /**
       * Annotation is only available in the source code.
       */
      SOURCE,
      /**
       * Annotation is available in the source code and in the class file, but not
       * at runtime. This is the default policy.
       */
      CLASS,
      /**
       * Annotation is available in the source code, the class file and is
       * available at runtime.
       */
      RUNTIME
  }

這個是一個枚舉類型,功能是控制Annotation的級別,值越大,權限越高,Annotation的作用范圍越大,下面分別解釋三個級別的作用范圍:
SOURCE:只在源文件此注解中有效,也就是,只要代碼已經編譯過了,權限被聲明為SOURCE的Annotation就無效;
CLASS: 文件或者代碼已經編譯了,這個時候還有效,當代碼跑起來了的時候,就沒有效果了;
RUNTIME:這個相當於最大權限,記住可用於任何時候,而我們在寫代碼的時候,都是希望在運行時候用,所以,一般情況下我們都是聲明為RUNTIME權限。

3、

  @Documented
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.ANNOTATION_TYPE)
  public @interface Target {
      ElementType[] value();
  }

這又是一個注解類,這個類的作用也是在我們自定義Annotation的時候聲明,然後確定自定義Annotation的作用類型是那個地方,它的取值就是下一個類所要講的,用法與Retention注解一樣,確切的說所有的Annotation都是這樣使用
4、

  public enum ElementType {
      /**
       * Class, interface or enum declaration.
       */
      TYPE,
      /**
       * Field declaration.
       */
      FIELD,
      /**
       * Method declaration.
       */
      METHOD,
      /**
       * Parameter declaration.
       */
      PARAMETER,
      /**
       * Constructor declaration.
       */
      CONSTRUCTOR,
      /**
       * Local variable declaration.
       */
      LOCAL_VARIABLE,
      /**
       * Annotation type declaration.
       */
      ANNOTATION_TYPE,
      /**
       * Package declaration.
       */
      PACKAGE
  }

這個類就是確定Annotation的作用位置,每個不同的值,對應的位置不相同
/**
* 作用於類,接口或枚舉
*/
TYPE,
/**
* 作用於字段,也就是成員變量.
*/
FIELD,
/**
* 作用於方法.
*/
METHOD,
/**
* 參數.
*/
PARAMETER,
/**
* 構造方法.
*/
CONSTRUCTOR,
/**
* 本地變量.
*/
LOCAL_VARIABLE,
/**
* 注解.
*/
ANNOTATION_TYPE,
/**
* 包名.
*/
PACKAGE
我只是把英文翻譯了一遍,如果有錯請指正。
基本用法介紹完了,接下來開始自定義Annotation
二、自定義Annotation
通過Android studio創建Annotation類,創建類的時候可以直接指定Annotation類型,這樣創建出來的文件如下:

  /**
   * Created by moon.zhong on 2015/2/14.
   */
  public @interface TestAnnotation {
  }

和接口非常像,只不過多了一個@,根據剛剛所講,需要再類上加上@Retention(RetentionPolicy.RUNTIME)來確定權限的大小,這裡直接采用最大權限,並指定作用的類型@Target(ElementType.METHOD),這裡指定作用於方法上面
自定義Annotation就完成了。

三、使用Annotation
寫任何代碼都不是用來看的,所以我們一定得知道如何使用它。
Annotation往往是跟反射結合起來使用的,我們在學習反思的時候,知道反射裡面很多方法獲取Annotation的值,也可以得出這樣一個結論,用到了Annotation的情況下,基本上就用到了反射,我們常說的一句話,無反射,不框架,這也是為什麼但大部分框架都大量使用Annotation的原因
這裡也是用反射的列子來說明Annotation的使用
編寫好自定義的Annotation,讓其作用范圍在類上面,

  /**
   * Created by moon.zhong on 2015/2/14.
   */
  @Retention(value = RetentionPolicy.RUNTIME)
  @Target(value = ElementType.TYPE)
  public @interface ClassAnnotation {
  }

定義好一個Bean的類,加上注解

  /**
   * Created by moon.zhong on 2015/2/14.
   */
  @ClassAnnotation
  public class Bean {
  }

通過反射來查看注解是否已經能正常使用

  public class MainActivity extends ActionBarActivity {

      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          Class mClass = Bean.class ;
          Annotation annotation[] = mClass.getAnnotations() ;
          for (Annotation a : annotation){
              Log.v("zgy","====getAnnotations===="+a.annotationType()) ;
          }
      }
  }

最後打印的log信息:zgy﹕ ====getAnnotations====interface moon.annotationdemo.ClassAnnotation

再來看看怎麼給自定義的Annotation設置值,像@Retention(RetentionPolicy.RUNTIME)一樣後面可以跟上一個值。在上面看log信息的時候,你是否發現了多打印了一個interface,而後面緊跟著的才是Annotation的全名,其實Annotation本省就是接口的一種,所以在聲明變量的時候,只需定義一個抽象方法即可,不需要實現,完全可以參照 public @interface Retention

  /**
   * Created by moon.zhong on 2015/2/14.
   */
  @Retention(value = RetentionPolicy.RUNTIME)
  @Target(value = ElementType.TYPE)
  public @interface ClassAnnotation {
      String print() ;
  }www.2cto.com

  /**
   * Created by moon.zhong on 2015/2/14.
   */
  @ClassAnnotation(print = "annotation")
  public class Bean {
  }

使用也是一樣的同 @interface Retention ,在Bean的類名上面加上@ClassAnnotation(print = “annotation”),這裡有一點需要注意,不能寫成@ClassAnnotation(“annotation”),因為這裡定義的方法是print(),如果換成value() 就可以省略。

    /**
     * Created by moon.zhong on 2015/2/14.
     */
    @Retention(value = RetentionPolicy.RUNTIME)
    @Target(value = ElementType.TYPE)
    public @interface ClassAnnotation {
        String value() ;
    }

    /**
     * Created by moon.zhong on 2015/2/14.
     */
    @ClassAnnotation("annotation")
    public class Bean {
    }
來測試下:
      for (Annotation a : annotation){
          Log.v("zgy","====print===="+((ClassAnnotation)a).print()) ;
      }

打印log的信息 zgy﹕ ====print====annotation
說明我們已經拿到了所設置的值,那麼接下來要實現什麼要的功能就看大家的智慧了。

四、總結:
老規矩,就像燒菜最後都要澆汁,這裡來做個總結,在定義Annotation的時候,需要注意兩點,一、通過@Retention(RetentionPolicy.RUNTIME)注解來確定聲明的Annotation的作用權限,這裡一般設為最大就可以了;二、通過@Target(ElementType.ANNOTATION_TYPE)注解來確定此注解的作用對象是誰。還有一點需要注意,自定義的Annotation如果定義了抽象方法,如果抽象方法名為value的時候,使用的時候可以省略,其他時候不能省略,個人建議,都加上。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved