阅读了下 Retrofit 的源码,非常喜欢它用注解来创建网络请求。 通过Retrofit创建一个网络请求非常方便,在注解里定义几个参数就可以非常方便的创建出来一个Call用于请求网络。
@POST("oauth2/token/")Call<AccessToken> getAccessToken(
@Field("username") String username,
@Field("password") String password,
@Field("grant_type") String grant_type,
@Field("scope") String scope,
@Field("client_id") String client_id
);
但是遗憾是它的注解都是在Runtime时候进行解析的, 这样的话就会用到反射,会影响我们执行的效率。 于是我就想可不可以像ButterKnife那样, 通过编译时候来处理注解然后自动生成我们想要的代码,这样子就不会影响程序的执行效率了。ButterKnife主要是通过创建一个Processor(继承于AbstractProcessor) 来在编译的时候来处理注解的, 然后再配合上JavaPoet 来生成自己想要的代码。
Step1
需要创建一个javalib 依赖库
然后在build.gradle加入AutoSerivce和JavaPoet依赖库
compile 'com.google.auto:auto-common:0.6'
compile 'com.google.auto.service:auto-service:1.0-rc2'
compile 'com.squareup:javapoet:1.7.0'
创建一个processor类然后继承abstractprocessor
@AutoService(Processor.class)
public class AutoProcessor extends AbstractProcessor
然后把你想处理的注解类注册一下
private Set<Class<? extends Annotation>> getSupportedAnnotations() { Set<Class<? extends Annotation>> annotations = new LinkedHashSet<>(); annotations.add(GET.class);
annotations.add(POST.class);
annotations.add(GETParam.class);
annotations.add(POSTParam.class);
annotations.add(Package.class);
return annotations;
}
private String parseParamNameValue(String value) {
int length = value.indexOf("(");
String parsedValue = value.substring(0, length);
return parsedValue;
}
这时候你可以在process函数里去处理相应的注解了。
Step2
如果想在编译时候调试代码
需要在gradle.properties里加入
org.gradle.daemon=true
org.gradle.jvmargs=agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5007
然后启动一个remote调试,配置上跟你properties相应的端口号
这时候通过terminal进入你项目的目录下
通过gradle启动daemon进程
输入gradle daemon
当守护进程启动起来后, debug刚刚创建的remote进行调试,接下来在你的代码上打上断点
最后输入gradle clean assembleDebug进行编译, 这时候会在你打的断点上停下来。
配置gradle环境变量
sudo vim ~/.bash_profile
GRADE_HOME=/Users/Admin/gradle;
export GRADE_HOME
export PATH=/opt/local/bin:/opt/local/sbin:$PATH:$GRADE_HOME/bin