Router 原理
2024-2-23
| 2024-8-2
0  |  Read Time 0 min
type
status
date
slug
summary
tags
category
icon
password
💡
内容提要:
  1. Java 注解
  1. Router 原理
      • URI 的组成
      • 使用 apt ,url 映射一个 class 类文件

注解

什么是注解?

注解又称为标注,用于为代码提供元数据。作为元数据,注解不直接影响你的代码执行,但也有一些类型的注解实际上可以用于这一目的。可以作用在类、方法、变量、参数和包等上。 你可以通俗的理解成“标签”,这个标签可以标记类、方法、变量、参数和包。

什么用处?

  • 生成文档
  • 标识代码,便于查看
  • 格式检查(编译时)
  • 注解处理(编译期生成代码、xml文件等;运行期反射解析;常用于三方框架)

常用注解

Java 注解

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。 Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。
Java内置了三种标准注解,其定义在java.lang中。
  • @Override,表示当前的方法定义将覆盖超类中的方法。
  • @Deprecated,被此注解标记的元素表示被废弃,如果程序员使用了注解为它的元素,那么编译器会发出警告。
  • @SuppressWarnings,关闭不当的编译器警告信息。
这几种注解我们平时开发中肯定经常用到,但是你可能很少看到注解原来的样子。如下为注解的类,可以看到,除了@符号的使用以外,它基本与Java固有语法一致。只是注解上又增加了其他注解。

Android 注解库

support.annotation 是 Android 提供的注解库,与 Android Studio 内置的代码检查工具配合,注解可以帮助检测可能发生的问题,例如 null 指针异常和资源类型冲突等。
使用前配置 在 Module 的 build.gradle 中添加配置 ”implementation 'com.android.support:support-annotations:版本号'“

Null 性注解

  • @Nullable 可以为 null
  • @NonNull 不可为 null

线程注解

线程注解可以检查某个方法是否从特定类型的线程调用。支持以下线程注解:
  • @MainThread
  • @UiThread
  • @WorkerThread
  • @BinderThread
  • @AnyThread
更多 android 注解请参考(利用注解改进代码检查)

元注解

元注解是由 java 提供的基础注解,负责注解其它注解。
元注解
说明
取值
@Target
表示该注解可以用在什么地方
ElementType.ANNOTATION_TYPE 可以应用于注释类型。 ElementType.CONSTRUCTOR 可以应用于构造函数。 ElementType.FIELD 可以应用于字段或属性。 ElementType.LOCAL_VARIABLE 可以应用于局部变量。 ElementType.METHOD 可以应用于方法级注释。 ElementType.PACKAGE 可以应用于包声明。 ElementType.PARAMETER 可以应用于方法的参数。 ElementType.TYPE 可以应用于类的任何元素。
@Retention
表示需要在什么级别保存该注解信息
SOURCE: 只在源码中有效 (编译时抛弃) CLASS: 在 class 文件中有效(即 class 保留) RUNTIME: 在运行时有效(即运行时保留)
@Documented
表示将此注解包含在Javadoc中
@Inherited
表示允许子类继承父类中的注解

注解处理器(Annotation Processing)

原理

Annotation Processing 原理:编译过程中读源码,然后⽣成新的代码⽂件,再放在⼀起进⾏编译

用法

Annotation Processing ⽤法:
  1. resources/META-INF/services/javax.annotation.processing.Processor(或者使用 AutoService)
  1. 继承 AbstractProcessor
  1. 重写 getSupportedAnnotationTypes() 和 process()
  1. 依赖 annotationProcessor先测试⽣成 java ⽂件的功能:手写或使用 javapoet
  1. 自动生成代码
  1. 添加依赖

调试

Router 原理

URI 基本概念

URI(Uniform Resource Identifier,统一资源标识符)是一个用于标识某一互联网资源名称的字符串。URI的组成如下图所示:
notion image

基于注解为 url 生成匹配对象

注解生成代码使用 apt ,如果需要 oop 模式代码可以借助 Poet 库,现在 kotlin 语言也支持注解生成代码(性能很差)。
Router 做的事情只有一个,就是将一条 Url 匹配到一个 Class。
比如 @Router("dafay://video/{video_id}/collection/{collection_id}") 我们使用 Routers.getDefault().resolve("dafay://video/1111111111/collection/0000000000") 进行解析,具体流程如下:
notion image
流程说明:
  1. Routers.getDefault() 类加载时在静态代码块里面进行初始化,把注解生成代码 Mapper 对象添加到一个 sMapperList 链表里面,并基于 priority 进行排序
  1. resolve 方法里面遍历 sMapperList 里面的 mapper 挨个进行 Matcher.match() 匹配,匹配分为两个部分,a. 匹配 Uri.parse(url) 转换后的 uri 的 Host 与 Scheme,b.匹配 path,匹配 path 并把对应的 key/value 添加到 bundle 中。 匹配结束包装成 MatchResult 对象。这个过程还可以为 Matcher 定义自己的匹配规则。
  1. filter 对 MatchResult 进行过滤,这个过程也可以添加在家的过滤规则。

使用 RouterManager 打开匹配对象

针对 Router 解析结果做一些额外工作,
例如通过 RouterManager.open(context,"dafay://video/1111111111/collection/0000000000")
notion image
流程说明:
  1. 生成 MatchResult 对象
  1. RouterDispatcher 处理
  1. RouterConsumer 消费,可以在这里不再打开页面而是做一下其它操作,在这之后 包装成 ZHIntent,
  1. 对 ZHIntent 进行转换
  1. 通过 startFragmentForResult 具体实现类去打开 ZhIntent,打开前对目标 Fragment 类注解进行获取,所有这个地方获取到的值应该会覆盖掉 Url 的参数值

Android 常见使用注解的框架

  • JakeWharton/butterknife:Android 开发的 View 注入框架,轻松的省去findViewById 来找到 View 对象的步骤
  • JUnit :Java语言的单元测试框架,可以大大缩短你的测试时间和准确度
  • Dagger2:依赖注入框架
  • Retrofit: RESTful 的 HTTP 网络请求框架的封装,网络请求的工作本质上是 OkHttp 完成,而 Retrofit 仅负责 网络请求接口的封装。Retrofit通过注解的方式,进行网络请求描述。
  • Arouter:阿里 Arouter

扩展

  • kapt 性能、ViewBinding vs DataBinding 性能
  • 编译优化(增量编译等)

参考文档

 
 
 
 
  • Android
  • 使用四段三次 Bézier 曲线拟合圆Dagger 使用
    • Utterance
    Catalog