美文网首页
apt编译时技术

apt编译时技术

作者: Android刘东 | 来源:发表于2020-08-10 18:12 被阅读0次

    github代码地址
    apt生成类返回数组方法
    生成文件如图:

    1597054567478.jpg WX20200810-181629@2x.png

    1.新建2个java项目如annotation模块.processor模块
    下文annotation模块简称A
    processor模块简称P
    2.A模块 新建一个MyAnnotation注解

    @Retention(RetentionPolicy.CLASS)       //表示编译时的注解
    @Target(ElementType.TYPE)
    public @interface MyAnnotation {
        //    int [] value() default {1,2,4};
        String text() default "";
    }
    
    

    3.P模块1)引入第三方

       implementation project(':annotation')//依赖刚刚创建的annotation模块
        implementation "com.google.auto.service:auto-service:1.0-rc4"//自动配置的
        annotationProcessor "com.google.auto.service:auto-service:1.0-rc4" //这个在gradle5.0以上需要的
        implementation 'com.squareup:javapoet:1.11.1'//方便编写代码的
    

    2)新建MyAnnotationProcessor类

    
    @AutoService(Processor.class)
    public class MyAnnotationProcessor extends AbstractProcessor {
    
        @Override
        public Set<String> getSupportedAnnotationTypes() {
            Set<String> supportTypes = new LinkedHashSet<>();
            supportTypes.add(MyAnnotation.class.getCanonicalName());
            return supportTypes;
        }
    
        @Override
        public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
     
            Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(MyAnnotation.class);
            for (Element mTypeElement : elements) {
                try {
                    generateActivityFile(mTypeElement, "com.liu.test").writeTo(processingEnv.getFiler());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return true;
        }
    
        public JavaFile generateActivityFile(Element mTypeElement, String packgeName) {
    
            MyAnnotation LRequest = mTypeElement.getAnnotation(MyAnnotation.class);
    
            MethodSpec.Builder injectMethod = MethodSpec.methodBuilder(TypeUtil.METHOD_NAME)
                    .addModifiers(Modifier.PUBLIC)
    .addParameter(TypeName.get(mTypeElement.asType()), "activity", Modifier.FINAL)
                    .addParameter(TypeName.get(mTypeElement.asType()), "activity", Modifier.FINAL);
            injectMethod.addStatement("android.widget.Toast.makeText" +
                    "(activity, $S,android.widget.Toast.LENGTH_SHORT).show();", LRequest.text());
            //generaClass
            TypeSpec injectClass = TypeSpec.classBuilder(mTypeElement.getSimpleName() + "$$InjectActivity")
                    .addModifiers(Modifier.PUBLIC)
                    .addMethod(injectMethod.build())
                    .build();
            return JavaFile.builder(packgeName, injectClass).build();
        }
    }
    
    

    4.android java模块引入

     implementation project(':annotation')
     annotationProcessor project(':processor')
    

    注意:项目中有Kotlin语言需要用该注解
    添加

    apply plugin: 'kotlin-kapt'  //头部添加
    
     implementation project(':annotation')
     kapt project(':processor')
    

    反射类InjectActivity

    
    import android.app.Activity;
    import android.util.ArrayMap;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import java.lang.reflect.Method;
    
    public class InjectActivity {
        private static final ArrayMap<String, Object> injectMap = new ArrayMap<String, Object>();
    
        public static void inject(Activity activity) {
            String className = activity.getClass().getName();
            try {
                Object inject = injectMap.get(className);
    
                if (inject == null) {
                    //加载build生成的类
                    Class<?> aClass = Class.forName(className + "$$InjectActivity");
                    inject = aClass.newInstance();
                    injectMap.put(className, inject);
                }
                //反射执行方法
                Method m1 = inject.getClass().getDeclaredMethod("inject", activity.getClass());
                m1.invoke(inject, activity);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    

    测试类TestActivity

    package com.liu.test;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.TextView;
    
    import androidx.annotation.Nullable;
    
    import com.liu.annotation.MyAnnotation;
    @MyAnnotation(text="123")
    public class TestActivity extends Activity {
    
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.test);
            final TextView mTextView = findViewById(R.id.mTextView);
            mTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    InjectActivity.inject(TestActivity.this);//调用build生成的类
                }
            });
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:apt编译时技术

          本文链接:https://www.haomeiwen.com/subject/tjnjdktx.html