欢迎转载,转载请标明出处:

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框架(二)的更多相关文章

  1. Android开发之手把手教你写ButterKnife框架(三)

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52672188 本文出自:[余志强的博客] 一.概述 上一篇博客讲了, ...

  2. Android开发之手把手教你写ButterKnife框架(一)

    欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/52662376 本文出自:[余志强的博客] 一.概述 JakeWhar ...

  3. 手把手教你写DI_1_DI框架有什么?

    DI框架有什么? 在上一节:手把手教你写DI_0_DI是什么? 我们已经理解DI是什么 接下来我们就徒手撸一撸,玩个支持构造函数注入的DI出来 首先我们回顾一下 构造函数注入 的代码形式, 大概长这模 ...

  4. 手把手教你写DI_2_小白徒手撸构造函数注入

    小白徒手撸构造函数注入 在上一节:手把手教你写DI_1_DI框架有什么? 我们已经知道我们要撸哪些东西了 那么我们开始动工吧,这里呢,我们找小白同学来表演下 小白同学 :我们先定义一下我们的广告招聘纸 ...

  5. 手把手教你写DI_0_DI是什么?

    DI是什么? Dependency Injection 常常简称为:DI. 它是实现控制反转(Inversion of Control – IoC)的一个模式. fowler 大大大神 "几 ...

  6. 网络编程懒人入门(八):手把手教你写基于TCP的Socket长连接

    本文原作者:“水晶虾饺”,原文由“玉刚说”写作平台提供写作赞助,原文版权归“玉刚说”微信公众号所有,即时通讯网收录时有改动. 1.引言 好多小白初次接触即时通讯(比如:IM或者消息推送应用)时,总是不 ...

  7. 只有20行Javascript代码!手把手教你写一个页面模板引擎

    http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...

  8. 手把手教你写Sublime中的Snippet

    手把手教你写Sublime中的Snippet Sublime Text号称最性感的编辑器, 并且越来越多人使用, 美观, 高效 关于如何使用Sublime text可以参考我的另一篇文章, 相信你会喜 ...

  9. 手把手教你写LKM rookit! 之 第一个lkm程序及模块隐藏(一)

    唉,一开始在纠结起个什么名字,感觉名字常常的很装逼,于是起了个这<手把手教你写LKM rookit> 我觉得: 你们觉得:...... 开始之前,我们先来理解一句话:一切的操作都是系统调用 ...

随机推荐

  1. Swagger+Asp.net WebApi实例

    第一步新建WebApi项目 文件-新建-项目,弹出以下页面 第二步,新建参数项目 第三步 1.自定义输入参数 2.定义公用输出参数 3.定义输出参数 4.定义返回模型 第四步,在webapi项目中新增 ...

  2. 如何设计一款APP,才能吸引用户眼球

    有APP分析机构研究表明,人们每天耗费在手机和平板上的平均时长为158分钟,其中127分钟是耗费在各类APP中,而仅有31分钟是花费在浏览网页上.随着人们对互联网的依赖性越来越强,移动APP发展迅速已 ...

  3. 有效防止softmax计算时上溢出(overflow)和下溢出(underflow)的方法

    <Deep Learning>(Ian Goodfellow & Yoshua Bengio & Aaron Courville)第四章「数值计算」中,谈到了上溢出(ove ...

  4. Evensgn 捡树枝

    问题 A: Evensgn 剪树枝 时间限制: 1 Sec  内存限制: 128 MB 题目描述 繁华中学有一棵苹果树.苹果树有 n 个节点(也就是苹果),n − 1 条边(也就 是树枝).调皮的 E ...

  5. StopAllSounds

    10月3日,在杭州市西湖景区,一只小松鼠不停地接受一道道食物,花生.玉米.饼干,可谓来者不拒,憨态可掬的模样吸引了众多围观者...Description   小松鼠开心地在树之间跳跃着,突然她停了下来 ...

  6. ●BZOJ 3123 [Sdoi2013]森林

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3123 题解: 主席树,在线,启发式合并 简单版(只有询问操作):[2588: Spoj 10 ...

  7. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  8. P1837 单人纸牌_NOI导刊2011提高(04)

    题目描述 单人纸牌游戏,共36张牌分成9叠,每叠4张牌面向上.每次,游戏者可以从某两个不同的牌堆最顶上取出两张牌面相同的牌(如黑桃10和梅花10)并且一起拿走.如果最后所有纸牌都被取走,则游戏者就赢了 ...

  9. poj 3348 Cow 凸包面积

    Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8122   Accepted: 3674 Description ...

  10. SAM维护的在线LCS

    题目大意: 给定两个字符串,存在三种操作,分别是在a,b串末尾加一个字符串,和询问两串的LCS 题解: Get新套路:把两串建在同一SAM上,将重合的位置合并为同一节点,再加个标记数组,如果两者的LC ...