从无到有手写ButterKnife框架-2
大约 2 分钟
#####导航 一、代码的演进 二、butterKnife反射调用 三、javapoet自动生成模板代码 四、apt与注解 五、注解支持多层继承 六、apt调试 七、javapoet语法
#####1、前言 javapoet解决重复模板代码编写问题 模板代码都类似,这样重复写来写去很烦 javapoet会是一阵强心剂
语法主要 @see https://github.com/square/javapoet 编写模板代码切记从上往下写,符合人的习惯,并且不会遗漏,
现写类,再写变量,再写方法,最后文件输出
#####javapoet模板代码编写 模板如下:
/**
* DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY CHENTONG.
*/
public class FirstActivity_ViewBinding implements Unbinder {
private FirstActivity target;
@UiThread
public FirstActivity_ViewBinding(FirstActivity target, View source) {
this.target = target;
target.helloTv = source.findViewById( R.id.helloTv );
}
@Override
public void unbind() {
target.helloTv = null;
}
}
1、模板要抽出变与不变的地方 不变的放在常量类中,变的用poet写 javapoet代码如下: //引入两个类 或者可以采用Class.forName()
public interface Unbinder {
void unbind();
//空方法
Unbinder EMPTY = new Unbinder() {
@Override public void unbind() { }
};
}
public class View {
}
//自动输出代码
public final class JavaPoet {
private static final String SUFFIX = "_ViewBinding";
private static final String JAVA_DOC = "DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY CHENTONG.
";
public static void main(String[] args) {
try {
gennerateCode(JavaPoet.class);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void gennerateCode(Class target) throws ClassNotFoundException, IOException {
//类全路径
String qualifiedName = target.getName().toString();
//包名
String packageName = qualifiedName.substring( 0, qualifiedName.lastIndexOf( "." ) );
//类文件
String fileName = target.getSimpleName() + SUFFIX;
//eg:public class FirstActivity_ViewBinding implements Unbinder
//构造类
TypeSpec.Builder typeBuilder = TypeSpec.classBuilder( fileName )
.addJavadoc( JAVA_DOC )
.addModifiers( Modifier.PUBLIC )
.addSuperinterface( Unbinder.class );
//eg:private FirstActivity target;
FieldSpec fieldSpec = FieldSpec.builder( target,"target",Modifier.PRIVATE ).build();
//field添加当前类中
typeBuilder.addField( fieldSpec );
//eg:@UiThread
// public FirstActivity_ViewBinding(FirstActivity target, View source) {
// this.target = target;
// target.helloTv = source.findViewById( R.id.helloTv );
// }
//构造方法
MethodSpec.Builder constructorBuilder = MethodSpec.constructorBuilder()
// .addAnnotation( UiThread.class )
.addModifiers( Modifier.PUBLIC )
.addParameter( target,"target" )
.addParameter( View.class,"source" );
constructorBuilder.addStatement( "this.target = target" );
constructorBuilder.addStatement( "target.helloTv = source.findViewById( R.id.helloTv )" );
//构造方法添加到类中
typeBuilder.addMethod( constructorBuilder.build() );
//eg:@Override
// public void unbind() {
// target.helloTv = null;
// }
//解绑方法
MethodSpec.Builder unbindBuilder = MethodSpec.methodBuilder( "unbind" )
.addAnnotation( Override.class )
.addModifiers( Modifier.PUBLIC )
.returns( void.class );
unbindBuilder.addStatement( "target.helloTv = null" );
//解绑方法添加类中
typeBuilder.addMethod( unbindBuilder.build() );
//创建文件 并且输出打印到到System.out
JavaFile.builder( packageName, typeBuilder.build()).build().writeTo( System.out );
}
}
以上代码,亲测可用
#####从无到有手写butterKnife框架 https://github.com/yinlingchaoliu/JavaPoetDemo