android架構師之路——自定義註解

定義註解

定義註解用的關鍵字是:@interface

元註解

元註解:元註解共有四種@Retention, @Target, @Inherited, @Documented

@Retention 註解位置

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

@Target 可以用來修飾哪些程序元素,如 TYPE, METHOD, CONSTRUCTOR, FIELD, PARAMETER等,未標註則表示可修飾所有

  •         @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) ///包  

@Inherited 是否可以被繼承,默認爲false

@Documented 是否會保存到 Javadoc 文檔中

 

註解得解析

處理運行時註解@Retention(RetentionPolicy.RUNTIME),註解會保留到運行時, 因此使用反射來解析註解

 ContentView得註解

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

 ContentView得解析

    /**
     * 設置佈局文件
     *
     * @param context
     */
    private static void initLayout(Object context) {
        int layoutId = 0;
        Class<?> aClass = context.getClass();
        ContentView contentView = aClass.getAnnotation(ContentView.class);
        if (null != contentView) {
            layoutId = contentView.value();
            try {
                Method method = context.getClass().getMethod("setContentView", int.class);
                method.invoke(context, layoutId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

 具體demo可以參考IOC原理,簡單實現BufferKnife

解析編譯時註解@Retention(RetentionPolicy.SOURCE) 解析編譯時註解需要繼承AbstractProcessor類, 實現其抽象方法

 註解BindView 代碼

@Target(ElementType.FIELD)  //聲明我們定義的註解是放在什麼上面的  也就是作用域
@Retention(RetentionPolicy.SOURCE)  //聲明我們定義的註解的生命週期   java--->class-->run
public @interface BindView {
    int value();
}

 BindView解析

// 指定要解析的註解
@SupportedAnnotationTypes("com.zkq.lib_annotations.BindView")
// 指定JDK版本
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class AnnotationCompiler extends AbstractProcessor {
    @Override
    public boolean process(Set annotations, RoundEnvironment roundEnv) {
        for (TypeElement te : annotations) {
            for (Element element : roundEnv.getElementsAnnotatedWith(te)) {
                TestAnnotation testAnnotation = element.getAnnotation(BindView.class);
                // do something
            }
        }
        return true;
    }
}

具體方式可以參考android架構師之路——APT實現Butterknife

發佈了37 篇原創文章 · 獲贊 0 · 訪問量 5160
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章