El uso de APT en la componentización del desarrollo de Android

¿Qué es APT?

APT (Herramienta de procesamiento de anotaciones)

Es una herramienta para procesar anotaciones. Detecta las anotaciones en los archivos de código fuente y produce automáticamente código basado en las anotaciones. Si desea que un procesador de anotaciones personalizado funcione normalmente, debe procesarlo a través de la herramienta APT. También se puede entender que solo después de que se declare la herramienta APT, el intérprete de anotaciones personalizado se puede ejecutar durante la compilación del programa.

Comprensión popular: de acuerdo con las reglas, ayúdanos a generar código y generar archivos de clase

Android Studio 3.4.1 + Gradle5.1.1 (versión recomendada)

¿Cómo usar APT en la componentización?

El desarrollo de componentes es de desacoplamiento y alto aislamiento. Cada módulo es independiente. Si queremos lograr una interacción directa entre cada componente, podemos utilizar los siguientes métodos:

  • La tecnología de reflexión y reflexión puede tener éxito, el costo de mantenimiento es alto y es probable que aparezcan restricciones de alta versión @hide
  • EvenTBus EventBean es muchos (uno a uno), uno a muchos será complicado y difícil de mantener (no he probado esto)
  • El costo del mantenimiento de la intención implícita está bien, pero es más problemático y requiere demasiadas acciones en el Manifiesto para mantenerse
  • BroadCastReceiver requiere un registro dinámico (después de 7.0), y la parte necesitada envía una transmisión
  • La carga de clases requiere una ruta precisa al nombre completo de la clase, el mantenimiento de la versión original es relativamente alto y es propenso a errores humanos

Entonces decir mucho, principalmente para decir que APT es una de las mejores soluciones para la interacción en el desarrollo en componentes.

Entonces, ¿cómo usarlo?

Primero, tome el salto de interfaz entre varios componentes como ejemplo:

La interfaz salta entre el módulo de la página principal (MainActivity) y el módulo de pedidos (OrderActivity):

Uno, crea una nueva clase de anotación

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)//RetentionPolicy.CLASS 编译期预编译的操作
public @interface ARouter {

    //详细路由器路径(必填),如:"/app/MainActivity"
    String path();

    // 从path中截取出来
    String group() default "";
}

2. Cree un nuevo ARouterProcessor para heredar AbstractProcessor para implementar el trabajo de anotación

ARouterProcessor hereda AbstractProcessor, a la clase con anotación ARouter, se genera una nueva clase para uso interactivo durante la compilación


@AutoService(Processor.class)
@SupportedAnnotationTypes("com.goodboy.annotation.ARouter")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
@SupportedOptions("content")
public class ARouterProcessor extends AbstractProcessor {

    //操作Element工具类
    private Elements elementUtils;

    //type(类信息)工具类
    private Types typeUtils;

    //用来输出警告,错误等日志
    private Messager messager;

    //文件生成器
    private Filer filer;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        elementUtils = processingEnvironment.getElementUtils();
        typeUtils = processingEnvironment.getTypeUtils();
        messager = processingEnvironment.getMessager();
        filer = processingEnvironment.getFiler();

        String content = processingEnvironment.getOptions().get("content");
        messager.printMessage(Diagnostic.Kind.NOTE,content);
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        if (set.isEmpty())return false;

        //获取项目中所有使用使用了ARouter注解的节点
        Set<? extends Element> elements = roundEnvironment.getElementsAnnotatedWith(ARouter.class);
        //遍历所有的类节点
        for (Element element : elements) {
            //类节点之上,就是包节点
            String packageName = elementUtils.getPackageOf(element).getQualifiedName().toString();
            //获取简单类名
            String className = element.getSimpleName().toString();
            messager.printMessage(Diagnostic.Kind.NOTE,"被注解的类有:" + className);
            // 最终我们想要生成的类文件 如:MainActivity$$ARouter
            String finalClassName = className + "$$ARouter";
            // 公开课写法,也是EventBus写法(https://github.com/greenrobot/EventBus)
            try {
                // 创建一个新的源文件(Class),并返回一个对象以允许写入它
                JavaFileObject sourceFile = filer.createSourceFile(packageName + "." + finalClassName);
                // 定义Writer对象,开启写入
                Writer writer = sourceFile.openWriter();
                // 设置包名
                writer.write("package " + packageName + ";\n");

                writer.write("public class " + finalClassName + " {\n");

                writer.write("public static Class<?> findTargetClass(String path) {\n");

                // 获取类之上@ARouter注解的path值
                ARouter aRouter = element.getAnnotation(ARouter.class);

                writer.write("if (path.equals(\"" + aRouter.path() + "\")) {\n");

                writer.write("return " + className + ".class;\n}\n");

                writer.write("return null;\n");

                writer.write("}\n}");

                // 最后结束别忘了
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return true;
    }
}

3. Agregue esta anotación a las clases MainActivity y OrderActivity, y use la clase generada para saltar al
código MainActivity

@ARouter(path = "/app/MainActivity")
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    public void jump(View view){
        Class<?> targetClass = OrderActivity$$ARouter.findTargetClass("/app/OrderActivity");
        startActivity(new Intent(this, targetClass));
    }
}

Código de actividad de pedido


@ARouter(path = "/app/OrderActivity")
public class OrderActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_order);
        Log.d("mile", "--->OrderActivity");
    }

    public void jump(View view) {
        Class<?> targetClass = MainActivity$$ARouter.findTargetClass("/app/MainActivity");
        startActivity(new Intent(this, targetClass));
    }
}

Resumen: el desarrollo de componentes consiste en utilizar APT de forma dinámica para generar clases interoperables

Supongo que te gusta

Origin blog.csdn.net/yanwenyuan0304/article/details/106020717
Recomendado
Clasificación