Android Studio中使用apt

栏目: 编程工具 · Android · 发布时间: 8年前

内容简介:Android Studio中使用apt

Android Studio中使用apt

一、前言

你还在对着枯燥的重复代码一味复制粘贴吗?这样跟搬砖有何区别?你是否曾想过:你用代码编写出一个自动化的APP,但为何代码本身却缺少了活力?掌握android-apt,杜绝重复代码,让你写代码如写诗般优雅。

二、何为apt?

apt意为:annotation processing tool(注解处理工具),这家伙可神奇了,它能通过注解,在编译期自动生成特定的 java 文件,实现自动编写代码。

问:有什么用?凭我自己本事能写出来的代码,为什么要自动化?大哥,你这是又想施展你的 复制粘贴大法 了吗?稍安勿躁,细看完这篇文章,你会爱上这家伙的。

鼎鼎大名的ButterKnife、Dagger2这两个开源库,相信你一定有听过,你应该知道我为什么提到它们了吧。没错!这两个开源库都是基于apt的。

三、说了这么多,要怎么用啊?别急,我们先搭建环境(基于gradle插件2.2.0以上版本)

1.在android studio中新建一个java module,用于存装注解处理逻辑,名字随便啦,反正我一般都取名:apt。很重要的事:在app module中添加注解处理依赖:annotationProcessor project(‘:apt’)

(解释原因:由于android的module中不包含有apt相关类,因此需要新建一个java module来编写apt逻辑。什么?你不信?不信你写个类继承AbstractProcessor试试)

Android Studio中使用apt

2.再次新建一个module(android、java都可以),用于存装注解,名字也随便,反正我这里取名为:anno,并且在app、apt的build.gradle文件下,添加依赖compile project(‘:anno’)(为什么要新建module去盛装注解类,而不放到app module或者apt module中去:最主要的原因就是app module与apt module不能直接相互依赖,至于为什么不能直接依赖,我就不细说了,总之一句话:不信你试试看就知道喽!)

3.在apt的build.gradle里,添加如下依赖。到此,我们的环境配置工作就告一段落了。 Android Studio中使用apt (其中:1.auto-service是用于注解后自动在特定路径下生成配置文件;2.javapoet是用于配合apt便捷生成java文件的工具。相信这样解释大家还云里雾里,不要着急,继续往下看)

四、环境搭建好了,接下来就是秀操作时间

1.首先,在anno module里新建一个注解类

@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.METHOD)
public @interface Test {
    String value();
}

2.在apt module里新建一个注解处理类,继承于AbstractProcessor

public class TestProcessor extends AbstractProcessor{
    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        return false;
    }
}

3.既然说apt是要自动生成java文件,那我们就需要拟构出一个目标类。假设我们要生成这样一个类

public class TestClass {

    public static void main(String[] args){
        System.out.println("Hallo world!");
    }

}

4.操作注解处理类,生成目标java文件

@AutoService(Processor.class)
@SupportedAnnotationTypes({
        "com.aop.anno.Test"
})
public class TestProcessor extends AbstractProcessor{

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {

        //生成TestClass类
        TypeSpec.Builder tb = TypeSpec.classBuilder("TestClass")
                .addModifiers(Modifier.PUBLIC);

        //生成main方法
        MethodSpec.Builder mb = MethodSpec.methodBuilder("main")
                .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
                .returns(void.class)
                .addParameter(String[].class, "args");

        //生成代码块,并添加到main方法中
        for(TypeElement e : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Test.class))){
            CodeBlock cb = CodeBlock.builder()
                    .addStatement("$T.out.println(\"$L + $L\")", System.class, 
                    e.getAnnotation(Test.class).value(), e.getSimpleName())
                    .build();
            mb.addCode(cb);
        }

        tb.addMethod(mb.build());

        JavaFile jf = JavaFile.builder("com.example.apt", tb.build()).build();
        //将代码写入java文件中
        try {
            jf.writeTo(processingEnv.getFiler());
        } catch (IOException e) {
            e.printStackTrace();
        }

        return true;
    }
}

大致说下步骤:

(1)添加@AutoService(Processor.class)注解,这个注解会自动在指定路径下生成一个配置文件:

apt/build/classes/main/META-INF/services/javax.annotation.processing.Processor;

(2)添加@SupportedAnnotationTypes注解,配置这个类所要处理的注解类型。(传入String类型参数,格式为:包名+类名);

(3)采用javapoet书写代码构建逻辑,具体用法去 这里 看看;

(4)生成代码块的主要逻辑是:遍历所有被@Test注解过的类,取出注解内容及类名打印出来。

5.在类上添加@Test注解,这里就用MainActivity来试试

@Test("abc")
public class MainActivity extends AppCompatActivity {

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

6.rebuild工程,在app/build/generated/source/apt/debug路径下找到目标java文件。至此,大功告成

Android Studio中使用apt

TestClass代码如下:

public class TestClass {
  public static void main(String[] args) {
    System.out.println("abc + MainActivity");
  }
}

五、然而并没什么暖用?

确实,到此为止,我们确实是用了几十行代码去生成了一个5行代码的TestClass,这种操作来说看起来可以用4个字来形容:闲得蛋疼。

然而,接下来的操作,会让你耳目一新。首先我们新建几个测试类,假如我们新建了这样4个测试类:ActivityA,ActivityB,ActivityC,ActivityD,并且都给他们加上注解@Test。然后rebuild一下,你会发现,我们的TestClass变了样:

public class TestClass {
  public static void main(String[] args) {
    System.out.println("A + ActivityA");
    System.out.println("B + ActivityB");
    System.out.println("C + ActivityC");
    System.out.println("D + ActivityD");
    System.out.println("abc + MainActivity");
  }
}

恍然大悟!原来,是这么玩的!这时候,你是否已经感觉到apt的魅力了呢?是的,它能帮你干掉重复代码,让你杜绝掉复制粘贴。

APT使用案例: APT实用案例一:状态模式之就算违背开闭原则又何妨?


以上所述就是小编给大家介绍的《Android Studio中使用apt》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Practical Vim, Second Edition

Practical Vim, Second Edition

Drew Neil / The Pragmatic Bookshelf / 2015-10-31 / USD 29.00

Vim is a fast and efficient text editor that will make you a faster and more efficient developer. It’s available on almost every OS, and if you master the techniques in this book, you’ll never need an......一起来看看 《Practical Vim, Second Edition》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

html转js在线工具
html转js在线工具

html转js在线工具