了解了butterknife的完毕原理后,研讨了一下apt技能,接着自己查阅相关资料,撸了一遍apt的完毕进程,因为看的资料比较老源码精灵旧,完毕进程较为曲折,所以把自己的完毕进程记载一下,便当新学习的小伙伴绕开这些坑。
ATP(Annotation processing tool)
Annotation processing tool也便是注解处理器了,原理是枸杞根据注解在代码编译的时分去生成相应的功用代码文件,打包的时分会跟着其他的源码一同打包成class文件,这样就避免了那些功appointment能在工作时全部用反射去完毕,然后提高了app的性能。
首要新建一个工程,然后新建一个java library module,取名binder_annotation,这儿咱们专门用来寄存Annotation文件,接着自定义一个宫颈癌Annotation,取名Bind源码精灵View:
@Retention(RetentionPolicy.CLASS) @Target(ElementTyp源码编辑器e.FIELD) public @interface BindView { int va源码是什么意思lue(); }
接着新建另一个java library module,取名binder_compiler,咱们在这儿做注解处理的作业,和生成相应的java文件的操作,
在这approve个module的gradle文件里增加如下配备:
plugins { id 'java-library' } java { sourceCompatibility = JavaVersion.VERSION_源码之家1_7 targetCompatibility = JavaVersion.VERSION_1_7 } dependen实例化是什么意思cies { implementation fileTree(dir: 'libs', include: ['*.jar']) //AutoService 首要的效果是注解 processor 类,并对其生成 META-INF 的配备信息。 implementation 'com.google.auto.service:auto-service:1.0-rc6' //处理gradle的版别源码编辑器bug,不增加会导致咱们的process类不被调用 annotationProcessor 'com.google.auto.service:auto-service:1.0-rc6' //JavaPoet 这个库的首要效果便是帮忙咱们通过类调appointment用的办法来生成代码。 implementation 'com.squareuapprovep:javapoet:1.10.0' implementation project(':binder_an源码notation') }
留心:Android Plugin for Gradle: >缓存视频变成本地视频;3.3.2的时分要增加 :
anno实例化servlet类反常tationProcessor ‘com.google.auto.缓存service:auto-service:1.0-rc6′ 这行依赖,这实例化需求是gradle的一实例化个版别bug,高版其他gradle不会去调用咱们编写好的process类,我在这儿就陷进去好久。
app module下的gradle文件做如下配备:
dependencies { implementappreciateation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompa缓存视频怎样转入相册t:appcompat:1.3.0' implementation 'com.google.android.material:matapplicationerial:缓存视频怎样转入本地视频1.3.0' implementation 'androidx.consappreciatetraintlayout:constraintlayout:2.0.4' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' annotationProcessor projeapprovect(':bin实例化是什么意思der_compilerapp下载') implementa源码编辑器tion project(':binder_annotation') }
接着新建BinderProcessor类,让它继承实例化servlet类反常AbstractProcessor,并加上@AutoService(Proc实例化servlet类反常essor.class)注解,这样它才会在代码编译期被执行:
@AutoService(Processor.class)
pub源码交易平台lic class BinderProcessor exteapprovends AbstractProcessor {
private Elements mElementUtils; ///处理Element的东西类
private HashMap<String,Bin实例化方针是什么意思derClassCreator>源码年代; mCreatorMap = new工商银行客服电话 Has龚俊hMap<>();//结构器东西的缓存m缓存视频变成本地视频ap
}
重写相关办法:
//初始化
@Ove工商银行rride
pub缓存视频兼并lic synchronized void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
//处理Elemen实例化一个类t的东西类,用于获取程序的元素,例如包、类、办法。
mElementUtils = processingEapprovenvironme源码分享网nt.getElementUtils();
}
//运用最新源码之家的版别
@Override
publ宫颈癌前期症状ic SourceVersion getSupportedSourceVersion() {
return SourceVersion.lapp下载atestSupported();
}
//支撑的注解类名集结,这儿咱们只做BindView的注解处宫颈癌前期症状理
@Override
public Set<String> getSupportedAnnotationTypes(缓存是什么意思) {
HashSet缓存视频怎样下载到手机相册&l缓存数据能够铲除吗t;Strin缓存视频在手机哪里找g> supportTypes = new LinkedHashSet<>();
supportTypes.add(B宫颈癌前期症状indView.class.getCanonicalName());
return supportTypes;
}缓存视频在手机哪里找
要点需求处理的办法是process(),相重视释在代码里,算是比较详细了,多看几遍应该看得懂:
@Overri实例化方针de p工商银行客服电话ublic boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) { //扫描整个工程里被BindView注解过的元素,会根据activity名来生成相应的东西类BinderClassCreator //BinderClassCreator里包含了生成相应的activity的_ViewBinding类,里面有做了findVie枸杞wById的作业 Set<? extends Element> elements = r巩立姣oundEnvironment.getElementsAnnotatedWith(BindVie缓存数据能够铲除吗w.class缓存); fo实例化需求r(Element element:elements){ VariableElemeapplicationnt variableElement = (Va工商银行riableElement) element;//强转 //回来此元素直接封装(非严峻意义上)的元素。 //类或接口被以为用于封装它直接声明的字段、办法、结构办法和成员类型 //这儿便是获取封装特征元素的类元素 TypeElement classElement = (TypeElement) variableElement.getEnclosingElement(); //获取简略类名 String fullCl缓存视频兼并assName = classElement.getQualifiedName().toStriGong(); //先在map缓存里approach取源码年代培训怎样样BinderClassCreator BinderClassCreator creator = mCreatorMap.ge缓存视频在手机哪里找t(fullClassName); if(creator == null){ creator = new BinderClassCreator(mElementUtils.getPackaapplegeOf(classElement),classElement); //保存在map里 mCreatorMap.put(fullClassName,c源码编辑器reator); } //获取元素注解信息 Bi工商银行ndView缓存视频怎样转入本地视频 bindAnnotation = variableElement.getAnnotation(BindView.class); int id = bindAnnotation.value(); creator.putElement(id,variableElement); } //通过javaPoet构建生成java文件 for(Strinappstoreg key:mCreatorMap.keySet()){ BinderClassCreator classCreator = mCreator实例化一个类Map.get(keygoogle); JavaFile javaFile = JavaFile.builder(classCreator.getmPackageName(), classCreator.generateJavaCode()).build(); try { javaFile.writ公积金eTo(processingEnv.getFiappointmentler()); } catch (IOException e) { e.printStackTrace(); } } retur缓存视频兼并n false; }
这儿用到宫颈癌前期症状一个Bi源码精灵nderClassCreator类,用来狗狗币帮忙构建相应activity__ViewBinding类的东西:
/**
*源码年代培训怎样样 @author: lookey
* @date: 2021/5/25
* 用来生成_BinderView类的东西类
*/
public实例化方针是什么意思 class BinderClassCreator {
publappreciateic static final String ParamNappearame = "vi缓存视频怎样转入相册ew";
private TypeEle实例化方针的关键字ment mTypeElement;//类元素
private String mPackageName;application
private String mBinderClassName;
private Ha宫颈癌shMap<Integer, Variable源码编辑器Eleme宫颈癌nt> mVariableElement = new HashMap<>();
public BinderClassCreator(PackageElement mPackageElement, Typ缓存eElement mTypeElement) {
this.mTypeElement = mTypeElement;
this.mPackageNam缓存视频怎样下载到手机相册e = mPacka缓存视频兼并geElement.实例化需求getQualifiedName().toString();
th缓存视频在手机哪里找is.mB实例化servlet类反常inderClassName = mTypeElement.getSimpleNam实例化需求e(源码资源站).实例化是什么意思toString()+"_ViewBinding";
}
public void putElement(int id,VariableElement variableE实例化方针的关键字lement){
mV源码分享网ariableElement.put(id,variableElement);
}
public String getmPac缓存视频怎样转入本地视频kageNa缓存视频怎样转入本地视频me() {
r狗狗币eturn mPackageName;
}宫颈癌前期症状
//生成java类,及相源码资本应的办法
public TypeSpec generateJavaCode(){
return TypeSpec.classBuilder(mBinderClassName)
.addModifiers(源码交易平台Modifier.PUBLIC) //public修饰
.addMethod(generateMethod()) //增加办法
.build();
}
private MethodSpec generateMethod(){缓存是什么意思
//获取类名
ClassName className = ClassName.best缓存视频怎样下载到手机相册Guess(mTypeElement.getQualifiedName().toString());
return MethodSpec.methodBuilder("bindView")
.addModifiers(Modifier.PUBLIC)
.returns(void.class)
.addParameter(className,ParamName)
.addCode(generateMethodCo实例化方针是什么意思d缓存视频怎样转入本地视频e())源码
.build();
}
private String generateMeapproachthodCode() {
StringB实例化方针有几种办法uilder code = new S源码精灵tringBuilder();
for (int id : mappointmentVariabl源码eElemapplicationent.keySet()) {
VariableElement variable缓存Element = mVariableElement.get(id缓存视频变成本地视频);
//运用注解的特征的称号
String name = variableElement.getSiGompleName().toString();
//运用注解的特征的类型
String type = variableEl实例化数组ement.asType().toString();
//view.name = (type)view狗狗币.findViewByIdapple(id)
String findVi实例化类ewCode = Param实例化servlet类反常Name + "." + name + "=(" + type + ")" + Param源码编辑器Name +
".findViewById(" + id + ");n";
code.append(findViewCode);
}
return code.toString();
}
}
再写一个东缓存视频兼并西类BinderViewTools 让咱们的activity调用,相似ButterKnife.bind(),通篇下来也就在这儿用到了反射:
/appearance** * @author: lookey * @date: 2021/5/25 */ public class BinderViewTools { public static void biappearnd(Activity activi实例化数组ty){ Class aClass = activit源码之家y.getClass(); try实例化 { Class<?> bindClass = Class.forName(aClass.getCanonicalName() + "_ViewBinding");//找到生成的相应的bind类 Method method = bindClass.getMethod("bindView", aClass); method.invoke(bindClass.newInstance(),a源码交易平台ctivity); } catch (Exception e) { e.printStackTr缓存数据能够铲除吗ace(); } } }
最后在activity运用一下,运用过程相似butterkn实例化需求ife:
package com.trendlab.aptex; import androidx.appcompat.app.App源码之家CompatAc缓存数据能够铲除吗tivity; import android.os.Bundle; import android.widget.TextVie巩立姣w; import com.trendlab.binder_annotation.BindView; publ实例化类ic class MainAapp下载ctivity extends AppCompatAct缓存视频怎样转入相册ivity { @Bin工商银行客服电话dView(R.id.tv111) public TextView tv111; @Override protected void onCrea源码交易平台te(Bundl源码分享网e savedInstan缓存视频变成本地视频ceState) { super.onCreate(savedInst缓存视频怎样下载到手机相册anceState); setContentView(R实例化是什么意思.layout.ac缓存视频怎样转入本地视频tivity_main); BinderViewTools.bind(this); //工作缓存时会去找到MainActivity_ViewBinding类,然后实例化一个方针,再调用findview()办法 tv111.setText("hello binder"); } }
工作编译一下,一切正常的话会在app module下生成这个文工商银行件:
模拟器工作成功:
整体做完仍是比较清楚的,要点是实例化一个类对javaPoet的熟练运用,和生成java文件的process()办法的构思,调试进程中遇到不能生成java文件,或许提示写入重appointment复报错的状况能够检验invalidate caches/restart 重启studio。
完毕
有一同学习的小伙伴能够重视下我的大众号——❤️程序猿养成方案❤️ 每周会守时做技能分享。快参与和我一同学习吧!
评论(0)