Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android注解原理與常用注解框架

Android注解原理與常用注解框架

編輯:關於Android編程

Android注解原理與常用注解框架

注解基本介紹 編寫注解 Android注解框架

注解的基本介紹

注解的定義
能夠添加到 Java 源代碼的語法元數據。類、方法、變量、參數、包都可以被注解,可用來將信息元數據與程序元素進行關聯,常見的注解如@Override, @Deprecated。

元注解
元注解是基本注解,所有的自定義注解都將會用到元注解,元注解主要有如下四個:

@Retention
這個注解表示注解的保留方式,有如下三種:
SOURCE:只保留在源碼中,不保留在class中,同時也不加載到虛擬機中
CLASS:保留在源碼中,同時也保留到class中,但是不加載到虛擬機中
RUNING:保留到源碼中,同時也保留到class中,最後加載到虛擬機中

具體的區別如下:
運行時注解就是就是運行時運用反射,動態獲取對象、屬性、方法等,一般的IOC框架就是這樣,可能會犧牲一點效率。
編譯時注解就是在程序編譯時根據注解進行一些額外的操作,大名鼎鼎的ButterKnife運用的就是編譯時注解,ButterKnife在我們編譯時,就根據注解,自動生成了一些輔助類。要玩編譯時注解呢,你得先依賴apt,r然後自己寫一個類繼承AbstractProcessor,重寫process方法,在裡面實現如何把配置或注解的信息變成所需要的類。

@Target
這個注解表示注解的作用范圍,主要有如下:

ElementType.FIELD 注解作用於變量

ElementType.METHOD 注解作用於方法

ElementType.PARAMETER 注解作用於參數

ElementType.CONSTRUCTOR 注解作用於構造方法

ElementType.LOCAL_VARIABLE 注解作用於局部變量

ElementType.PACKAGE 注解作用於包

@Inherited

是否可以被繼承,默認為 false

@Documented

是否會保存到 Javadoc 文檔中

基本注解
java中常用的注解有如下三個

@Override: 表示該方法是重寫父類中的方法,編譯的時候會檢查該方法,如果這個方法不是父類中存在的將會報錯 @Deprecated: 表示該方法時已經過時的,表示該方法有風險或者有更好的替代方法 @SuppressWarnings: 表示在編譯的時候忽略某種錯誤,如版本檢查等

編寫注解

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface TestAnnonation {
        String name() default "";
        int Id()  default 0;
    }

注解關鍵字時@interface,然後上面標注為元注解,表示只能修飾方法並且加載到虛擬機中,裡面時這個注解所具有的屬性,name, id,我們在給方法加注解的時候設置相應的值。

    @TestAnnonation(name = "android" , Id = 1)
    private void testAnno(){

    }

上面我們在一個方法上面添加注解,然後我們通過下面的方法將這個注解打印出來

    private void outputAnnoDetail(Class clazz){
        Method [] methods = clazz.getDeclaredMethods();
        for(Method method  : methods) {
            TestAnnonation testAnnonation  = method.getAnnotation(TestAnnonation.class);
            if (testAnnonation != null) {
                Log.d("anonation", "name------>" + testAnnonation.name() + "------>Id------>" + testAnnonation.Id());
            }
        }
    }

上面的打印結果就是

name------>android------>Id------>1

這是一個運行時注解,注解的作用就是標記一個可以被識別的作用域,可以被其他地方獲取解釋或者被編譯機識別等作用。

Android注解框架

ButterKnife
ButterKnife注解框架是大家常用的注解框架,它主要作用是綁定View並且綁定View常用的監聽事件,下面是其中一個注解
@Retention(CLASS) @Target(FIELD)
public @interface BindView {
  /** View ID to which the field will be bound. */
  @IdRes int value();
}

通過上面的代碼可以看出,ButterKnife的注解保留方式為CLASS模式,也就是會保留到class中但是不會背加載到虛擬機中,這個時候我們就要看下它的AbstractProcessor,一般標注為Class的都會重寫AbstractProcessor類,這樣在虛擬機進行編譯的時候就會做相應的處理。
主要看一下幾個方法:

@Override
public Set getSupportedAnnotationTypes() {
    Set types = new LinkedHashSet<>();
    for (Class annotation : getSupportedAnnotations()) {
      types.add(annotation.getCanonicalName());
    }
    return types;
  }

  private Set> getSupportedAnnotations() {
    Set> annotations = new LinkedHashSet<>();

    annotations.add(BindArray.class);
    annotations.add(BindBitmap.class);
    annotations.add(BindBool.class);
    annotations.add(BindColor.class);
    annotations.add(BindDimen.class);
    annotations.add(BindDrawable.class);
    annotations.add(BindFloat.class);
    annotations.add(BindInt.class);
    annotations.add(BindString.class);
    annotations.add(BindView.class);
    annotations.add(BindViews.class);
    annotations.addAll(LISTENERS);

    return annotations;
  }

上面的方法主要表明會處理哪些注解

@Override
public boolean process(Set elements, RoundEnvironment env) {
    Map bindingMap = findAndParseTargets(env);

    for (Map.Entry entry : bindingMap.entrySet()) {
      TypeElement typeElement = entry.getKey();
      BindingSet binding = entry.getValue();

      JavaFile javaFile = binding.brewJava(sdk);
      try {
        javaFile.writeTo(filer);
      } catch (IOException e) {
        error(typeElement, "Unable to write binding for type %s: %s", typeElement, e.getMessage());
      }
    }

    return true;
  }

然後就是在編譯的時候的具體處理過程,這個過程主要時先找到並解析注解,然後生成java文件,這樣在虛擬機真正執行的時候就不用去查找和解析,也就不會耗時了。
* EventBus
EventBus是使用運行時注解,主要的作用是在運行的時候會去查找所有被注解的方法,然後再去解析注解。運行時注解會影響程序的性能,畢竟在運行的時候有一個查找的過程,所以運行時注解的作用一般是標記一個作用區。

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