美文网首页
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编译时技术

    github代码地址apt生成类返回数组方法生成文件如图: 1.新建2个java项目如annotation模块.p...

  • Android APT注解处理器

    一、编译时技术简介APT ( Annotation Processing Tool ) 注解处理工具 ; 编译时技...

  • APT的使用2

    APT(Annotation Processing Tool) 注解编译时工具。现在越来越多的框架使用apt技术来...

  • APT的使用1

    APT(Annotation Processing Tool) 注解编译时工具。现在越来越多的框架使用apt技术来...

  • 13_APT

    深入解析APT技术&IOC核心思想 APT(Annotation Process Tool),是一种在代码编译时处...

  • Android路由跳转-ARouter框架

    相关基础可查阅Android路由跳转-基础 ARouter框架图框架图 APT注解编译时使用APT技术处理@Rou...

  • Android自动生成代码的2种方式

    利用 APT 技术在编译期生成代码 简介: APT(Annotation Processing Tool 的简称)...

  • Android 利用 APT 技术在编译期生成代码

    参考资料 Android 利用 APT 技术在编译期生成代码 Android 打造编译时注解解析框架 这只是一个开...

  • ButterKnife源码分析

    原理: APT(Annotation Processing Tool)编译时解析技术(现在已经改成了谷歌的更强大的...

  • 手写APT

    APT(Annotation Processing Tool)注解处理器,一种编译时技术。 在javac中的,用来...

网友评论

      本文标题:apt编译时技术

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