本例主要为了实践AbstractProcessor和JavaPoet结合使用,通过注解方式实现:
TextView textView = (TextView)findViewById(R.id.label);
具体步骤如下:
1、build.gradle配置文件
implementation 'com.google.auto.service:auto-service:1.0-rc3'
implementation 'com.squareup:javapoet:1.8.0'
2、Annotation类
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface TextAnnotation {
int value();
}
3、Processor类
@SupportedAnnotationTypes({"com.example.annotation.TextAnnotation"})
@SupportedSourceVersion(SourceVersion.RELEASE_7)
@AutoService(Processor.class)
public class MyProcessor extends AbstractProcessor {
private static final String GEN_CLASS_SUFFIX = "$$Injector";
private Types mTypeUtils;
private Elements mElementUtils;
private Filer mFiler;
private Messager mMessager;
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
mTypeUtils = processingEnv.getTypeUtils();
mElementUtils = processingEnv.getElementUtils();
mFiler = processingEnv.getFiler();
mMessager = processingEnv.getMessager();
}
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(TextAnnotation.class);
if(elements == null || elements.size() == 0)
return true;
for (Element element : elements) {
if (element.getKind()!= ElementKind.FIELD) {
mMessager.printMessage(Diagnostic.Kind.ERROR, "is not a FIELD", element);
}
if (!isView(element.asType())){
mMessager.printMessage(Diagnostic.Kind.ERROR, "is not a View", element);
}
TypeElement clazz = (TypeElement) element.getEnclosingElement();
String packageName = mElementUtils.getPackageOf(clazz).asType().toString();
String className = clazz.getSimpleName().toString();
String type = element.asType().toString();
String name = element.getSimpleName().toString();
int resourceId = element.getAnnotation(TextAnnotation.class).value();
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("inject")
.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
.returns(void.class)
.addParameter(ClassName.get(packageName, className), "arg").addStatement("$N.$L = ($T)arg.findViewById($L)", "arg", name, element.asType(), resourceId);
TypeSpec helloWorld = TypeSpec.classBuilder(className + GEN_CLASS_SUFFIX)
.addModifiers(Modifier.PUBLIC)
.addMethod(methodBuilder.build())
.build();
JavaFile javaFile = JavaFile.builder("linjw.demo.processordemo", helloWorld)
.build();
try {
javaFile.writeTo(mFiler);
}catch (Exception e){
e.printStackTrace();
}
}
return true;
}
private boolean isView(TypeMirror type) {
List<? extends TypeMirror> supers = mTypeUtils.directSupertypes(type);
if (supers.size() == 0) {
return false;
}
for (TypeMirror superType : supers) {
if (superType.toString().equals("android.view.View") || isView(superType)) {
return true;
}
}
return false;
}
}
4 、生成的中间类
5、注解应用到Android中
public class MainActivity extends AppCompatActivity {
@TextAnnotation(R.id.label)
TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivity$$Injector.inject(this);
textView.setText("就这么简单!");
}
}
demo 地址: https://download.csdn.net/download/l540538550/11329523