Android AbstractProcessor结合JavaPoet 实例

本例主要为了实践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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值