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

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. Spring-Cloud(三)Eureka注册中心实现高可用

    前言: spring-cloud为基础的微服务架构,所有的微服务都需要注册到注册中心,如果这个注册中心阻塞或者崩了,那么整个系统都无法继续正常提供服务,所以,这里就需要对注册中心进行集群,换言之,高可 ...

  2. p2p项目总结

    1.关于ajax请求所要注意的地方:$.psot(url,json,callback,type) (1)url路径问题,在html中写绝对路径不能用EL表达式,EL表达式只能在jsp中使用 (2)js ...

  3. MQTT客户端库-Paho GO

    为了加深理解,本文是翻译文章.原文地址 Paho GO Client   语言 GO 协议 EPL AND EDL 官网地址 http://www.eclipse.org/paho/ API类型 As ...

  4. 2-XOR-SAT

    [题目描述]SAT(Satisfiability,可满足性)问题是著名的 NP 完全问题,它的内容是:判断由有限个布尔变量及其“非”用“或”操作连接起来的表达式组是否可以都为 TRUE.2-SAT 问 ...

  5. 51 nod 1406 与查询

    1406 与查询 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题   有n个整数.输出他之中和x相与之后结果为x的有多少个.x从0 ...

  6. 【tyvj】刷题记录(1001~1099)(64/99)

    1001:排序完按照题意做即可. #include<cstdio> #include<iostream> #include<cmath> #include<a ...

  7. 【UOJ UNR #1】火车管理

    来自FallDream的博客,未经允许,请勿转载,谢谢. 题面 考虑用可持久化线段树直接维护每个点在不同时刻,第一辆车的编号. 这样3操作就变成了区间赋值,1操作变成区间和 2操作的话,只需要查询一下 ...

  8. SPOJ Query on a tree V

    You are given a tree (an acyclic undirected connected graph) with N nodes. The tree nodes are number ...

  9. Windows10下配置python的环境变量

    从官网下载Windows下的python版本,一路按照默认进行安装. 安装之后配置环境变量的步骤如下: 1,点"我的电脑",右键选"属性". 2,选择" ...

  10. PHP内核之旅-1.生命周期

    1.SAPI接口 PHP具体应用的编程接口. 2.开始和结束 PHP开始执行以后会经过两个主要的阶段: 处理请求之前的开始阶段和请求之后的结束阶段. 1.1开始阶段: 1.1.1 模块初始化阶段(MI ...