缘起
随着 App 的成长,我们难免会遇到以下这些需求:
- H5 跳原生界面
- Notification 点击调相关界面
- 根据后台返回数据跳转界面,例如登录成功后跳不同界面或者根据运营需求跳不同界面
- 实现 AppLink 的跳转
为了解决这些问题,App 一般都会自定义一个 scheme 跳转协议,多端都实现这个协议,以此来解决各种运营需求。今天就来解析下QMUI 最新版 QMUISchemeHandler
的设计与实现。
一个 scheme 的格式大概是这样子:
schemeName://action?param1=value1¶m2=value2
例如:
qmui://home?tab=2
从技术角度来讲,实现 scheme 的跳转并不是件很难的事情,就是下面两个步骤:
- 解析 scheme
- 根据解析结果跳转指定界面
但是写代码时如果不加以设计,就容易是堆一堆的 if else。例如:
if(action=="action1"){
doAction1(params)
}else if(action=="action2"){
doAction2(params)
}else {
...
}
每当有新的 scheme 添加时,就去添加一个 if,直到它逐渐变成一段巨长的烂代码,改都改不动。因而我们要勤思考、多重构,尽早通过设计出优良的框架来解放自己的双手。
对于 if else 这类的重构,一个基本的方式就是用查表法,将所有的条件以及其所要执行的行为放在一个 map 里,然后使用时通过去查询这个 map 而获取要执行的行为。而我们可以通过注解配合代码生成的方式构建这个 map,从而减少我们代码的编写量。除此之外,我们还需要考虑各种功能性需求:
- 可以设置拦截器 interceptor,例如跳某些界面,如果是非登录的状态,可能需要跳转到登录界面
- 参数可以指定一些基础类型, scheme 所携带的参数的值都是字符串,但我们希望它可以方便的转换成我们需要的基础类型
- 同一个 action 可以根据参数的不同而有不同的跳转行为,例如都是跳转书籍详情,漫画书籍和普通书籍要跳转的界面可能不一样
- 如果当前界面已经是目标界面,可以选择刷新当前界面或者启动一个新界面
- 对于 QMUI,是同时支持 Activity 和 Fragment 的,因而 scheme 也要同时支持这两者
- 可以自定义新界面的实例化方法
接口设计
任何一个库的开发,为了让业务使用方足够舒心,既要保证库的功能足够强大,也要保证使用的方便性,QMUI Scheme 对外主要是QMUISchemeHandler
这个入口类, 以及 ActivityScheme
和 FragmentScheme
两个注解。