apt编译时技术

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生成的类
            }
        });
    }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。