当前位置: 首页 > 科技观察

Android转鸿蒙系列:ButterKnife(一)

时间:2023-03-13 14:54:41 科技观察

更多内容请访问:与华为官方共建的鸿蒙技术社区https://harmonyos.51cto.com关于ButterKnife移植的第一篇文章:先介绍一下基础知识,明白什么是apt,最后输出一个乞丐版的BufferKnife注入工具。这是理解BufferKnife源码的基础。第二篇占坑:详解BufferKnife的移植。apt技术基础知识的实际应用:AndroidDatabinding绑定视图ButterKnife绑定视图Dagger2注入变量ARouter生成路由表确实好很多而且非常重要。Apt是一个生产力工具!什么是贴切?通俗地说:apt是javac对外开放的一个插件,可以让javac在编译时获取注解(Annotation),并进行相应的处理(多为生成一些java代码)。从上图可以看出,apt是对java源文件进行处理,并在编译过程中进行干预。相比之下,asm等工具处理字节码文件,并介入后期的编译。apt和javac之间的协议apt和javac同意在META-INF/services/javax.annotation.processing.Processor文件中注册apt插件。这样apt就参与了javac的编译过程。写个乞丐版的BufferKnife不想看文,直接看源码,点https://gitee.com/andych008/aptDemo初始代码fork自https://github.com/LiMubai2017/aptDemo,先感谢作者。乞丐版的BufferKnife是一个视图注入工具。它主要做了3件事。它解析注解,处理注解(生成模板类文件),通过模板类注入视图对象。将被注射。通常,注解定义在一个单独的模块中(比如命名为apt-annotation),因为它会被apt-compiler和apt-api都依赖,属于公共代码。apt-compiler是apt的主要代码,完成注解的解析和模板文件的生成。apt-api是一个外部工具类,供用户用来完成注入操作。该应用程序是一个演示,其中定义了@BindView(value=ResourceTable.Id_text_helloworld)publicTexttestTextView;第一步:解析注解,在apt-compiler中定义类BindViewProcessor继承javax.annotation.processing.AbstractProcessor并实现getSupportedAnnotationTypes()方法注册Annotations进行解析。第二步:处理注解(生成模板文件)实现BindViewProcessor中的process()方法来处理注解。先了解javax.lang.model.element.Element和javax.lang.model.type.TypeMirror,详细解释参考这里。简单的说:Element就是描述Java语言元素的类,比如包、类、变量、参数等等。TypeMirror是一个描述Element类型的类,比如各种基本类型,数组,类等等,很容易混淆,只有用多了才能真正理解。例如:demo中的testTextView是VariableElement元素类型TypeElementenclosingElement=(TypeElement)variableElement.getEnclosingElement();//获取TypeElementStringfield=variableElement.getSimpleName().toString();//testTextViewTypeMirrortypeMirror=variableElement.asType();//ohos.agp.components.Text使用log()方法用Messager登录来验证我们的理解。log(String.format("element:(%s)%s",element.getKind(),element));log(String.format("bind:(%s)%s<-->id=%d",typeMirror,field,id));输出日志:注:element:(FIELD)testTextView注:bind:(ohos.agp.components.Text)testTextView<-->id=16777222在generateCodeByPoet()方法中,使用javapoet生成Template代码MainAbility$$Autobind.java(文件路径app/build/generated/source/annotation/debug/com/example/apt_demo/MainAbility$$Autobind.java)关于javapoet的使用,直接看官方文档:https://github.com/square/javapoet解释一下下面的代码,让大家对javapoet有一个直观的认识MethodSpec.BuilderinjectMethod=MethodSpec.methodBuilder("inject")//生成一个方法,方法名是inject.addAnnotation(Override.class)//给方法添加“Override.class”注解.addModifiers(Modifier.PUBLIC)//给方法添加访问控制字符.addParameter(Object.class,"target")//给方法添加参数method.addStatement("$Tsubstitute=($T)target",className,className);//在方法体中定义一个语言名称上面的代码生成如下代码(我用java代码生成java代码,javapoet就是这样做的):@Overridepublicvoidinject(Objecttarget){MainAbilitysubstitute=(主要能力ity)target;}看完以上,如果觉得有难度,请使用JavaWriter生成java文件。你会觉得javapoet真香。第三步:通过模板类注入视图对象在apt-api中,我们定义了一个AutoBind.java类来封装模板类MainAbility$$Autobind.java的操作。根据模板类的命名规则xxx$$Autobind,通过反射实例化MainAbility$$Autobind.java,调用inject方法完成视图的注入。总结一下,apt只是一个工具。在这个工具的框架下,如何处理注解是难点。BufferKnife和我们的“乞丐版BufferKnife”本质上没有区别。除了注入视图,它还支持事件绑定和增量编译。更多信息请访问:Harmonyos.51cto.com,与华为官方合作打造的鸿蒙技术社区