github代码地址
apt生成类返回数组方法
生成文件如图:
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生成的类
}
});
}
}
网友评论