Android Studio中使用apt
来源:互联网 发布:口红哪个牌子好 知乎 编辑:程序博客网 时间:2024/06/06 00:00
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试试)
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里,添加如下依赖。到此,我们的环境配置工作就告一段落了。
(其中:1.auto-service是用于注解后自动在特定路径下生成配置文件;2.javapoet是用于配合apt便捷生成java文件的工具。相信这样解释大家还云里雾里,不要着急,继续往下看)
四、环境搭建好了,接下来就是秀操作时间
1.首先,在anno module里新建一个注解类
@Retention(RetentionPolicy.SOURCE)@Target(ElementType.TYPE)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文件。至此,大功告成
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
- Android Studio中使用apt
- ubuntu 下使用apt 安装android studio
- android studio apt-complier
- Android studio添加apt
- Java8中使用APT
- Android Studio使用ButterKnife各种错误解决Plugin with id 'android-apt' not found.
- Android studio 中使用GeenDao
- Android studio中使用fastjson
- Android Studio中使用AIDL
- android studio 中使用aidl
- Android Studio中使用NDK
- Android Studio 中使用IconFont
- Android Studio 中使用Lambda
- android studio中使用lambda
- Android studio 中使用svn
- Android studio中使用pinyin4j
- Android studio 中使用Jni
- librtmp实时消息传输协议(RTMP)库代码浅析
- 第三讲 跳转结果的方式
- SPOJ
- 【PMP认证考试之个人总结】第 4 章 项目范围管理
- 基本网络知识
- Android Studio中使用apt
- day6 linux操作基础命令 第三弹
- BZOJ 4027 [HEOI2015] 兔子与樱花
- 面试例题5—感知器实现and函数
- Java基础
- 从UIWebView到WKWebView
- Hadoop三剑客:hdfs、yarn、mapreduce
- 函数
- 第四讲 数据的处理