安卓to鸿蒙系列:ButterKnife(一)

系统
文章由鸿蒙社区产出,想要了解更多内容请前往:51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com

[[398862]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

本文是关于ButterKnife的移植的第一篇:

先介绍基础知识,理解apt是什么,最终输出一个乞丐版BufferKnife注入工具。

这是读懂BufferKnife源码的基础。

第二篇占坑:具体讲解BufferKnife的移植。

基础知识

apt技术的实际应用:

  • Android Databinding绑定view
  • ButterKnife绑定view
  • Dagger2注入变量
  • ARouter生成路由表

真的好多,很重要。apt就是生产力工具!

什么是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作为一款view注入工具,主要干了3件事,

解析注解

处理注解(生成模板类文件)

通过模板类注入view对象

第0步:准备工作

先定义注解BindView,被@BindView标记的变量会被注入。

一般注解都定义在一个单独的module(如取名apt-annotation),因为它会被apt-compiler和apt-api都依赖,属于公共代码。

apt-compiler是apt的主要代码所在,完成注解的解析、模板文件的生成。

apt-api则是对外的工具类,供用户使用,完成注入操作。

app是demo,其中定义了

  1. @BindView(value = ResourceTable.Id_text_helloworld) 
  2. public Text testTextView; 

 第一步:解析注解

在apt-compiler中定义类BindViewProcessor继承javax.annotation.processing.AbstractProcessor,实现其中的getSupportedAnnotationTypes()该方法注册要解析的注解。

第二步:处理注解(生成模板文件)

在BindViewProcessor中实现process()方法,处理注解。

先理解javax.lang.model.element.Element和javax.lang.model.type.TypeMirror,参考这里 有详细的解释。

  • 简单讲:
  • Element是描述java语言元素的类,比如包、类、变量、参数等。
  • TypeMirror是描述Element类型的类,比如各种基本类型、数组、类等。

很绕,只有多用才能真正理解。比如:demo中testTextView就是VariableElement元素类型

  1. TypeElement enclosingElement = (TypeElement) variableElement.getEnclosingElement();//获取代表MainAbility的TypeElement 
  2.  
  3. String field = variableElement.getSimpleName().toString();//testTextView 
  4. TypeMirror typeMirror = variableElement.asType();//ohos.agp.components.Text 

 通过log()方法,可以使用Messager打日志,验证我们的理解。

  1. log(String.format("element : (%s) %s ", element.getKind(), element)); 
  2. log(String.format("bind : (%s) %s <--> id = %d", typeMirror, field, id)); 
  3. 输出日志: 
  4. 注: element : (FIELD) testTextView  
  5. 注: bind : (ohos.agp.components.Text) testTextView <--> id = 16777222 

 generateCodeByPoet()方法中,使用javapoet生成模板代码MainAbility$$Autobind.java(文件路径app/build/generated/source/annotation/debug/com/example/apt_demo/MainAbility$$Autobind.java)

关于javapoet的使用,直接看官方文档吧:https://github.com/square/javapoet

解释一下下面这段代码,让大家对javapoet有一直观的认识

  1. MethodSpec.Builder injectMethod = MethodSpec.methodBuilder("inject")//生成一个方法,方法名是inject 
  2.         .addAnnotation(Override.class)//给方法加上"Override.class"注解 
  3.         .addModifiers(Modifier.PUBLIC)//给方法加上访问控制符 
  4.         .addParameter(Object.class, "target")//给方法加上参数 
  5.         .addStatement("$T substitute = ($T)target", className, className);//在方法体内定义一条语名 

 上面的代码生成下面的代码(我用java代码生成java代码,这就是javapoet干的事情):

  1. @Override 
  2. public void inject(Object target) { 
  3.   MainAbility substitute = (MainAbility)target; 

 看完上面这一坨,你如果觉得难。请用JavaWriter生成java文件。你就会觉得javapoet真香。

第三步:通过模板类注入view对象

在apt-api中,我们定义一个AutoBind.java类封装对模板类MainAbility$$Autobind.java的操作。

按照模板类的命名规则xxx$$Autobind,通过反射实例化出MainAbility$$Autobind.java,调用 其中的inject方法,完成view的注入。

总结

apt只是一个工具,在这套工具框架下,怎么处理注解才是难点。

BufferKnife和我们的“乞丐版BufferKnife”本质上没有区别。除了注入view,还支持事件绑定、增量编译。

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-07-26 10:09:43

鸿蒙HarmonyOS应用

2021-04-26 09:46:10

鸿蒙HarmonyOS应用

2021-04-27 09:22:28

鸿蒙HarmonyOS应用

2019-06-20 16:07:12

鸿蒙安卓操作系统

2013-12-12 16:23:53

安卓进化AndroidGoogle

2020-09-10 09:30:03

鸿蒙安卓操作系统

2016-12-14 14:43:11

ButterknifeAndroid

2021-10-26 06:59:40

Windows 11操作系统微软

2021-05-20 05:27:50

安卓系统应用安卓12

2016-12-28 09:30:37

Andriod安卓平台依赖注入

2011-11-23 09:57:28

安卓驱动

2013-09-11 09:43:06

苹果安卓

2013-11-04 14:49:34

安卓

2018-02-09 08:59:47

安卓FuchsiaiOS

2018-05-09 10:39:21

Google安卓 系操作系统

2021-05-18 15:44:13

IOS安卓鸿蒙

2021-06-04 05:13:22

鸿蒙

2019-07-12 16:00:25

华为禁令开发

2013-10-17 10:17:41

安卓

2014-12-09 11:15:06

邮箱安卓移动端
点赞
收藏

51CTO技术栈公众号