Android开发之手把手教你写ButterKnife框架(二)
欢迎转载,转载请标明出处:
http://blog.csdn.net/johnny901114/article/details/52664112
本文出自:【余志强的博客】
上一篇博客Android开发之手把手教你写ButterKnife框架(一)我们讲了ButterKnife是什么、ButterKnife的作用和功能介绍以及ButterKnife的实现原理。
本篇博客主要讲在android studio中如何使用apt。
一、新建个项目, 然后创建一个module名叫processor
新建module的时候一定要选择 Java Library 否则在后面会找不到AbstractProcessor。
分别在app和processor 的文件夹下的build.gralde添加如下配置:
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
二、然后在建一个module名叫annotation,主要用来保存项目用到的annotation.
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.CLASS;
@Retention(CLASS) @Target(FIELD)
public @interface BindView {
int value();
}
三、新建MainActivity 字段上加上注解,如下:
public class MainActivity extends AppCompatActivity {
@BindView(R.id.text_view)
TextView textView;
@BindView(R.id.view)
TextView view;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
三、在processor module下新建一个ButterKnifeProcessor 继承AbstractProcessor.
@SupportedAnnotationTypes("com.chiclaim.processor.annotation.BindView")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class ButterKnifeProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
StringBuilder builder = new StringBuilder()
.append("package com.chiclaim.processor.generated;\n\n")
.append("public class GeneratedClass {\n\n") // open class
.append("\tpublic String getMessage() {\n") // open method
.append("\t\treturn \"");
// for each javax.lang.model.element.Element annotated with the CustomAnnotation
for (Element element : roundEnv.getElementsAnnotatedWith(BindView.class)) {
String objectType = element.getSimpleName().toString();
// this is appending to the return statement
builder.append(objectType).append(" says hello!\\n");
}
builder.append("\";\n") // end return
.append("\t}\n") // close method
.append("}\n"); // close class
try { // write the file
JavaFileObject source = processingEnv.getFiler().createSourceFile("com.chiclaim.processor.generated.GeneratedClass");
Writer writer = source.openWriter();
writer.write(builder.toString());
writer.flush();
writer.close();
} catch (IOException e) {
// Note: calling e.printStackTrace() will print IO errors
// that occur from the file already existing after its first run, this is normal
}
return true;
}
}
@SupportedAnnotationTypes(…) 里面的参数是我们需要处理的注解
四、在processor module主目录下resources目录
然后新建META-INF目录,然后在META-INF下新建services 然后新建一个文件名为 javax.annotation.processing.Processor, 里面的内容就是刚刚新建的ButterKnifeProcessor的qualified name :
com.chiclaim.butterknife.processor.ButterKnifeProcessor
当然也可以用新建这么多文件夹,只需要加入google AutoService,这样就会自动完成上面的操作。
@SupportedSourceVersion(SourceVersion.RELEASE_7)
@AutoService(Processor.class)
//AutoService自动生成文件(in processor.jar): META-INF/services/javax.annotation.processing.Processor
public class ButterKnifeProcessor extends AbstractProcessor
五、添加android-apt支持
在全局的build.gradle添加添加apt支持,com.neenbedankt.gradle.plugins:android-apt:1.8,如下所示:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
ext {
sourceCompatibilityVersion = JavaVersion.VERSION_1_7
targetCompatibilityVersion = JavaVersion.VERSION_1_7
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
分别在app module的build.gradle添加 apply plugin 如下所示:
apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'
六、添加module之间的依赖
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
testCompile 'junit:junit:4.12'
compile project(':annotation')
compile project(':processor')
compile project(':butterknife')
}
//把processor module生成的jar拷贝到app libs目录
task processorTask(type: Exec) {
commandLine 'cp', '../processor/build/libs/processor.jar', 'libs/'
}
//build processor 生成processor.jar
processorTask.dependsOn(':processor:build')
preBuild.dependsOn(processorTask)
如下图所示:
会在app module的build的目录下生成代码,如:
public class GeneratedClass {
public String getMessage() {
return "button says hello!\nimageView says hello!\ntextView says hello!\nview says hello!\n";
}
}
据此,在android studio 使用apt就介绍完毕了。
具体的可以查看github代码:https://github.com/chiclaim/study-butterknife
下一篇将介绍如何实现ButterKnife注入初始化View功能。
参考文档
http://blog.stablekernel.com/the-10-step-guide-to-annotation-processing-in-android-studio
Android开发之手把手教你写ButterKnife框架(二)的更多相关文章
- Android开发之手把手教你写ButterKnife框架(三)
欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52672188 本文出自:[余志强的博客] 一.概述 上一篇博客讲了, ...
- Android开发之手把手教你写ButterKnife框架(一)
欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52662376 本文出自:[余志强的博客] 一.概述 JakeWhar ...
- 手把手教你写DI_1_DI框架有什么?
DI框架有什么? 在上一节:手把手教你写DI_0_DI是什么? 我们已经理解DI是什么 接下来我们就徒手撸一撸,玩个支持构造函数注入的DI出来 首先我们回顾一下 构造函数注入 的代码形式, 大概长这模 ...
- 手把手教你写DI_2_小白徒手撸构造函数注入
小白徒手撸构造函数注入 在上一节:手把手教你写DI_1_DI框架有什么? 我们已经知道我们要撸哪些东西了 那么我们开始动工吧,这里呢,我们找小白同学来表演下 小白同学 :我们先定义一下我们的广告招聘纸 ...
- 手把手教你写DI_0_DI是什么?
DI是什么? Dependency Injection 常常简称为:DI. 它是实现控制反转(Inversion of Control – IoC)的一个模式. fowler 大大大神 "几 ...
- 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接
本文原作者:“水晶虾饺”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.引言 好多小白初次接触即时通讯(比如:IM或者消息推送应用)时,总是不 ...
- 只有20行Javascript代码!手把手教你写一个页面模板引擎
http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...
- 手把手教你写Sublime中的Snippet
手把手教你写Sublime中的Snippet Sublime Text号称最性感的编辑器, 并且越来越多人使用, 美观, 高效 关于如何使用Sublime text可以参考我的另一篇文章, 相信你会喜 ...
- 手把手教你写LKM rookit! 之 第一个lkm程序及模块隐藏(一)
唉,一开始在纠结起个什么名字,感觉名字常常的很装逼,于是起了个这<手把手教你写LKM rookit> 我觉得: 你们觉得:...... 开始之前,我们先来理解一句话:一切的操作都是系统调用 ...
随机推荐
- TNS-12560: Message 12560 not found; No message file for product=network, facility=TNS报错
[oracle@localhost bin]$ ./lsnrctl startLSNRCTL for Linux: Version 12.2.0.1.0 - Production on 17-APR- ...
- 关于Goldwell平台推出赠金及手数奖励
关于Goldwell平台推出赠金及手数奖励 Goldwell平台是一家拥有30多年现货黄金经验平台,平台位于柬埔寨金边,是一家国际衍生品的经纪公司.Goldwell平台它对柬埔寨金融市场和客户绝对的承 ...
- java中关于&、&&、|、||之间的区别和运算
关于&.&&.|.||之间的区别和运算 在逻辑运算中: 普通与&:要判断所有的判断的条件 短路与&&:如果前面一个判断条件出现false,则后续的判断条 ...
- 031718-js变量、数据类型、运算符
1.关键字.标识符.变量(是一个名称,最好用字母开头,对大小写敏感).常量 (是有数据类型的一个值) 变量: ①定义并赋值 ②使用 2.数据类型:数字 字符串 布尔 null undefi ...
- Spring Cloud Eureka 自我保护机制
Eureka Server 在运行期间会去统计心跳失败比例在 15 分钟之内是否低于 85%,如果低于 85%,Eureka Server 会将这些实例保护起来,让这些实例不会过期,但是在保护期内如果 ...
- 直接插入排序算法:ArrayList实现和数组实现
直接插入排序算法思想: 排序区间R[1..n]: 在排序的过程中,整个排序区间被分为两个子区间: 有序区R[ 1 ... i-1 ]和无序区R[ i ... n ]: 共进行n-1趟排序,每趟排序都是 ...
- UVALive - 3938:"Ray, Pass me the dishes!"
优美的线段树 #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring& ...
- SpringCloud学习之SpringCloudBus
一.spring-cloud-bus是什么? 回答这个问题之前,我们先回顾先前的分布式配置,当配置中心发生变化后,我们需要利用spring-boot-actuator里的refresh端点进行手动刷新 ...
- Python【第三课】 函数基础
本篇内容 函数基本语法及特性 嵌套函数 递归函数 匿名函数 高阶函数 内置函数 1.函数的基本语法及特性 1.1 函数概念 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提 ...
- 手机上的ROM与RAM
ROM:read only memory翻译为只读存储器. RAM:read access memory翻译为随机存储器. 下面是一张手机的配置参数表. 简单来说,RAM就是真正意义上的内存,而ROM ...