android 开发之 APT 技术

841 阅读2分钟

APT,就是Annotation Processing Tool 的简称,就是可以在代码编译期间对注解进行处理,并且生成Java文件,减少手动的代码输入。一些大名鼎鼎的框架如 Retrofit, Arouter 都运用了 APT 技术。

在本片文章中我们将利用 APT 技术实现类似 ARouter 的路由功能.

不多说,先附上本文中的代码地址:APTdemo

github.com/square/java…

实现效果

常用的 Activity 跳转方式:

startActivity(new Intent(MainActivity.this, TwoActivity.class));

我们希望通过以下方式达到 Activity 跳转的目的:

SRouter.getInstance().navigate(MainActivity.this, "router_two");

注解

创建annotationlibrary, 首先我们在 library 中定义注解,通过它我们可以找到哪些 Activity 需要添加到路由中

@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface Router {
    String name();
}

注解处理器 - compile

创建compilelibrary,依赖 annotation模块, 注意创建的时候选择 java-libray, 创建RouterProcessor类继承自 AbstractProcessor。我们需要实现 4 个方法,前3个方法简单的写法很固定,简单讲一下他们的作用吧;

  1. init()方法可以初始化拿到一些使用的工具,比如文件相关的辅助类 Filer;元素相关的辅助类Elements;日志相关的辅助类Messager;
  2. getSupportedSourceVersion()方法返回 Java 版本;
  3. getSupportedAnnotationTypes()方法返回要处理的注解;

其中最核心的是 process()方法,通过javapoet 再结合注解我们就可以成相应的类。 最终我们希望生成的类是这样的:

public final class Router?GroupApp implements IRouterGroup {
    private Map<String, String> routeMap = new HashMap();

    public Router?GroupApp() {
        this.routeMap.put("router_two", "com.slyser.aptdemo.TwoActivity");
    }

    public String getActivityName(String routeName) {
        return null != this.routeMap && !this.routeMap.isEmpty() ? (String)this.routeMap.get(routeName) : "";
    }
}

实现代码并不复杂,就是写起来很繁琐,还好 javapoet 为我们省了不少事。

注册注解处理器

编译的时候 JVM 怎么找到我们自定义的注解处理器?这个时候就要用到 SPI 机制。简单的用法就是在 compile 模块下新建 resources/META-INF/services 文件,创建这个文件很容易出错,大家可以使用 google 出品的 auto-service,通过注解就可以很方便的问我们创建相应的文件

添加auto-service的 gradle 依赖:implementation 'com.google.auto.service:auto-service:1.0-rc3'

核心库 - api

创建 api library, 该库很简单,就只有 SRouter 一个类,核心就是反射创建注解处理器生成的对象,拿到 Activity 的 Class,完成 activity 的跳转.

使用

在 Activity 上添加注解

@Router(name = "router_two")
public class TwoActivity extends AppCompatActivity

跳转

SRouter.getInstance().navigate(this, "router_two");

这样一个简单的路由跳转就完成了

总结

APT技术其实就是自定义注解和注解处理器,在编译期间生成Java文件,类似于IOC控制反转,可以方便的进行解耦,在多模块开发时可以基于APT技术构造一套路由框架,去除startActivity等造成的类依赖。