Android APT

6438 ワード

Android APT
文書ディレクトリ
  • Android APT
  • 注記タイプ
  • 注記の処理
  • 運転時注記の処理
  • コンパイル時注記の処理
  • javapoet

  • APT annotation processing tool注記処理ツール
    注記タイプ
  • 注記構文
  • 注記@interfaceキーワードで定義
    @Retention(RetentionPolicy.CLASS)
    @Target({ElementType.FIELD, ElementType.TYPE})
    public @interface MyAnnotation {}
    

    Javaには5つの注釈があります:@Retention,@Documented,@Target,@Inherited,@Repeatable.以下では、それぞれについて説明します.
  • @Retention注釈の生存時間を説明するために使用され、3つの値がある:
     RetentionPolicy.SOURCE:          ,               
     
     RetentionPolicy.CLASS:         ,           JVM 
     
     RetentionPolicy.RUNTIME:            ,      JVM ,                
            ButterKnife             ,       javapoet        
    
  • @Target注記が機能するターゲットを指定します.値は次のとおりです.
  • ElementType.PACKAGE:      
            
    ElementType.TYPE:     、  、   
        
    ElementType.ANNOTATION_TYPE:        
        
    ElementType.FIELD:       
        
    ElementType.CONSTRUCTOR:         
        
    ElementType.METHOD:       
        
    ElementType.PARAMETER:         
        
    ElementType.LOCAL_VARIABLE:         ,          
        
               ,           ,     Demo:
    @Target({ElementType.FIELD, ElementType.TYPE})
    
  • @Documented名前から分かるように、この注釈はドキュメントに関連しており、注釈の要素をJavadocに含めることができる役割を果たしています.
  • @Inherited Inheritedは継承の意味ですが、注釈自体が継承できるわけではありません.親のSuperClassがこのクラスの注釈で修飾されていることを意味します.その子のSubClassは、注釈の修飾がなければ、親のこの注釈を継承します.栗を挙げる:
  • @Inherited
    @Target(ElementType.Type)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Test {}
        
    @Test
    public class A {}
        
    public class B extens A {}
        
      :  Test @Inherited  ,A Test  ,B  A(B       ),  B    Test    。
    
  • @Repeatableという言葉は繰り返し可能な意味でjava 1です.8に導入され、新しい特性が計算されます.どのような注釈が何度も適用されるのか、通常は注釈が複数の値を取ることができ、栗を挙げる:
  •     Person[] value();
    }
    
    @Repeatable(Persons.class)
    public @Interface Person {
        String role() default ""
    }
    
    @Person("artist")
    @Person("developer")
    @Person("superman")
    public class Me {}
    
      :@Person @Repeatable  ,  Person            Me , Repeatable      ,          ,      @Person。
    

    注記の処理
    実行時注記の処理
    実行時の注釈処理は、一般的には反射的に注釈を取得し、EventBusのスレッド処理の注釈など、自分の望む処理を行い、メインスレッドまたはサブスレッドで、反射して対応するスレッドの中で処理します!たとえば
     /**
         *     InjectView
         *
         * @param activity   InjectView     
         */
        public static void inject(Activity activity) {
            Field[] fields = activity.getClass().getDeclaredFields();
            //                ,       ,     private     
            AccessibleObject.setAccessible(fields, true);
            for (Field field : fields) {
                boolean needInject = field.isAnnotationPresent(InjectView.class);
                if (needInject) {
                    InjectView anno = field.getAnnotation(InjectView.class);
                    int id = anno.id();
                    if (id == -1) continue;
                    View view = activity.findViewById(id);
                    Class fieldType = field.getType();
                    try {
                        // View   field     
                        field.set(activity, fieldType.cast(view));
                    } catch (Exception e) {
                        Log.e(InjectView.class.getSimpleName(), e.getMessage());
                    }
                }
            }
        }
    

    コンパイル時の注記の処理
    コンパイル時の注釈処理には、対応する注釈の処理に協力する注釈処理器が必要である、一般的には、プロセッサによって注釈を取得した後javapoetによって、ButterKnifeがコンパイル時にfindviewbyidのファイルを生成するなど、所望のファイルを生成する.
  • の処理手順は以下の通りである:
  • annotationとAbstractProcessorは、2つの異なるmoudleに
  • を構築する必要があります.
  • AbstractProcessor
  • を継承
    @AutoService(Processor.class) //       annotation       META_INF      
    public class MyProcessor extends AbstractProcessor
    {
        private Types    mTypeUtils;
        private Elements mElementUtils;
        private Filer    mFiler;
        private Messager mMessager;
    
        @Override
        public synchronized void init(ProcessingEnvironment processingEnvironment)
        {
            super.init(processingEnvironment);
    
            //            
            mTypeUtils = processingEnv.getTypeUtils();
            mElementUtils = processingEnv.getElementUtils();
            mFiler = processingEnv.getFiler();
            mMessager = processingEnv.getMessager();
        }
    
        @Override
        public SourceVersion getSupportedSourceVersion()
        {
            //   java  
            return SourceVersion.latestSupported();
        }
    
        @Override
        public Set getSupportedAnnotationTypes()
        {
            //     
            Set annotations = new LinkedHashSet<>();
            annotations.add(ZyaoAnnotation.class.getCanonicalName());
            return annotations;
        }
    
        @Override
        public boolean process(Set extends TypeElement> set, RoundEnvironment roundEnvironment)
        {
            //              ,    Java  
            return false;
        }
    }
    

    javapoet
  • 例えばActivity
  • を構築したい
     public static void main(String[] args){
            //   
            TypeSpec.Builder classBuild=TypeSpec.classBuilder("HomeActivity")
                    .addModifiers(Modifier.PUBLIC)
                    .superclass(ClassName.get("android.app","Activity"));
            //    
            MethodSpec onCreate= MethodSpec.methodBuilder("onCreate")
                    .addAnnotation(ClassName.get("java.lang","Override"))
                    .addModifiers(Modifier.PROTECTED)
                    .addParameter(ClassName.get("android.os","Bundle"),"savedInstanceState")
                    .addStatement("super.onCreate(savedInstanceState)")
                    .addStatement("setContentView(R.layout.activity_main)")
                    .build();
            //     
            JavaFile javaFile= JavaFile.builder("com.comers.processor",classBuild.addMethod(onCreate).build()).build();
            //   
            try {
                javaFile.writeTo(new File("/Volumes/world/works/NewFrame/app/src/main/java/com/comers/shenwu/kotlin"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    

    リファレンスhttps://www.jianshu.com/p/7454a933dcaf https://blog.csdn.net/wsw_123/article/details/81018161 https://blog.csdn.net/weixin_34007020/article/details/87137483//abstractProcessorメソッドの詳細https://blog.csdn.net/wenyingzhi/article/details/80415014//javaopet詳細https://blog.csdn.net/l540675759/article/details/82931785//javapoet詳細https://juejin.im/post/584d4b5b0ce463005c5dc444