apt編譯時技術(shù)

github代碼地址
apt生成類返回數(shù)組方法
生成文件如圖:

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')//依賴剛剛創(chuàng)建的annotation模塊
    implementation "com.google.auto.service:auto-service:1.0-rc4"http://自動配置的
    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);
            }
            //反射執(zhí)行方法
            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);//調(diào)用build生成的類
            }
        });
    }

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容