标签:activityName writer 笔记 学习 ButterKnife variableElement 注解 activity class
为什么使用?
1. 方便处理adapter里的viewHolder的绑定问题
2. 简化代码,节省开发时间(代替android中对view的相关操作,减少大量的findViewById和setClickListener)
3. 不影响运行性能和效率
4. 代码清晰,可读性强
原理:
利用注解和注解处理器针对每个类生成相对应的类,通过butterknife.bind(this)绑定这个类,通过反射机制操作类里的方法和变量
注解:相当于一个标记
注解处理器:相当于大脑
前期准备:
使用butterknife:
implementation 'com.jackewharton:butterknife:9.0.0' 申明注解库
annotationProcessor 'com.jackwharton:butterknife-compiler:9.0.0' 申明注解处理器
自己写注解器:
annotationProcessor 'com.google.auto.service:auto-service:1.0-rc4' 注解处理器申明(编译时运行)
implementation 'com.google.auto.service:1.0-rc4'
申明java版本
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
添加插件:
dependencies {
classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0'
}
简单说明:
绑定:Butterknife.bind(this)
右键可以一键生成(需要添加插件:android butterknife zelezry),使用的时候鼠标需要停留在layoutView上(Generate - Generate Butterknife injections)
可以绑定所有的source资源:@BindString(R.string.name) String appName;
使用:
重点需要注册这个类是一个注解处理器:@AutoService(Processor.class)
继承AbstractProcessor类实现相关方法进行相应处理操作
1. 初始化工作(生成一个java文件)
//生成文件对象
Filter filter;
* 实现init方法,参数是processingEnvironment(初始化数据)
filter = processingEnvironment.getFilter();
* 实现getSupportedAnnotationTypes(说明注解处理器要处理哪些注解)
Set<String> types = new HashSet<>();
types.add(BindView.class.getCanonicalName());//BindView是自己定义的注解名称
最后return这个types
* 实现getSupportedSourceVersion(申明当前注解支持的java版本)
// 直接return一个sourceVersion对象
return processingEnv.getSourceVersion() -- processingEnv是父类成员变量
* 实现process(写文件 - 包含俩个参数set结合和RoundEnviroment)
说明:可以读取三种类型节点
1. 类节点 - TypeElement
2. 方法节点 - ExecutableElement
3. 变量节点 - VariableElement
//获取模块中用到BindView的成员变量节点集合(指App中所有activity控件)
Set<? extends Element> elementsAnnotateWith = roundEnvironment.getElementAnnotatesWith(接口类.class);
//遍历文件进行Activity分离
Map<String,List<VeriableElement>> map = new HashMap();
/***额外的说明,注解处理器可以做很多事情,因为可以拿到类对象******
Class class = variableElement.getEnclosingElement().getClass();
Filed[] = class.getDeclaredFields();//拿到类里所有变量
Method[] class.getDeclaredMethods();//拿到类里所有方法
*****************************************************************/
for(Element element: elementsAnnotatedWith){
VariableElement variableElement = (VariableElement)element;
//获取类节点
String activityName = variableElement.getEnclosingElement().getSimpleName().toString();
List<VariableElement> variableElementList = map.get(activityName);
if(variableElementList == null){
variableElementList = new ArrayList();
map.put(activityName,variableElementList);
}
variableElementList.add(variableElement);
}
//开始写文件
if(map.size() > 0){
Write write = null;
Iterator<String> iterator = map.ketSet().iterator();
while(iterator.hasNext()){
String activityName = iterator.next();
//获取到activity所对应的集合
List<VariableElement> variableElementList = map.get(activityName);
//获取父节点 - 类节点
TypeElement enclosingElement= (TypeElement)variableEElementList.getEnclosingElement();
//通过成员变量到的包名
String packageName = processingEnv.getElementUtils().getPackageOf(enclosingElement).toString();
JavaFileObject sourceFile = filer.createSourceFile(packageName+"."+activityName+"_ViewBinding");
writer = sourceFile.openWriter();
writer.write("package "+packageName+";\n");//写类的第一句,包名
writer.write("import "+packageName+".IBinder;\n");//import引入包名
writer.write("public class "+activityName+"_ViewBinding implements
IBinder<"+packageName+"."+activityName+">{\n");
writer.write("@OverRide\n public void bind("+packageName+"."+activityName+" target){");
//遍历所有的控件
for(VariableElement variableElement:variableElements){
//获取到控件名字
String variableName = variableElement.getSimpleName().toString();
//获取控件id
int id = variableElement.getAnnotation(BindView.class).value();
//获取控件类型
TypeMirror typeMirror = variableElement.asType();
writer.write("target."+variableName+"=("+typeMirror+")target.findViewById("+id+");\n);
}
writer.write("{\n}\n");
}
}
最后在finally中
if(writer != null){
try(){
writer.close();
}catch(IOException e){
}
}
后续使用:
创建一个类(该类要实现接口类)
实现bind(){
}
类(java类执行注解类)
public static void bind(Activity activity){
activity.getClass().getName()+"_ViewBinding";
Class<T> aClass = Class.forName(name);
IBind iBinder = aClass.newInstance();
iBinder.bind(activity);
}
接口类<T>(把当前activity传进去)
void bind(T target);//可能是activity、fragment、service等
标签:activityName,writer,笔记,学习,ButterKnife,variableElement,注解,activity,class 来源: https://blog.csdn.net/wuhongbo5885251/article/details/100697192
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。