转载请注明链接:https://blog.csdn.net/feather_wch/article/details/81605300
可以从文章末尾的参考资料中进行学习
Android 路由框架ARouter详细使用教程
版本:2019/2/3-1(12:28)
1、什么是路由?
- 根据路由表将页面请求分发到指定页面
- 映射页面跳转关系,也包含跳转相关的一切功能。
2、使用场景
- App接收到一个通知,点击通知打开App的某个页面
- 浏览器App中点击某个链接打开App的某个页面
- 运营活动需求,动态把原生的页面替换成H5页面
- 打开页面需要某些条件,先验证完条件,再去打开那个页面
- 不合法的打开App的页面被屏蔽掉
- H5打开链接在所有平台都一样,方便统一跳转
- App存在就打开页面,不存在就去下载页面下载,只有Google的App Link支持
3、为什么要有路由?
- 显示Intent:项目庞大以后,类依赖耦合太大,不适合组件化拆分
- 隐式Intent:协作困难,调用时候不知道调什么参数
- 每个注册了Scheme的Activity都可以直接打开,有安全风险
- AndroidMainfest集中式管理比较臃肿
- 无法动态修改路由,如果页面出错,无法动态降级
- 无法动态拦截跳转,譬如未登录的情况下,打开登录页面,登录成功后接着打开刚才想打开的页面
- H5、Android、iOS地址不一样,不利于统一跳转
- 复杂的业务场景下(比如电商),灵活性比较强,很多功能都是运营人员动态配置的,比如下发一个活动页面,事先并不知道具体的目标页面,提前做好页面映射,便可以自由配置。
- App一般都会走向组件化、插件化的道路,而组件化、插件化的前提就是解耦,首先要做的就是解耦页面之间的依赖关系。
- 简化代码。数行跳转代码精简成一行代码。
4、怎样是好的路由库
- 使用简单、入侵低、便于维护
5、路由库的本质
- 注册再转发,围绕着转发可以进行各种操作,拦截,替换,参数获取等等
- 其他Apt、Rxjava都只是为了方便使用
6、应用场景
- 从外部URL映射到内部页面,以及参数传递与解析
- 跨模块页面跳转,模块间解耦
- 拦截跳转过程,处理登陆、埋点等逻辑
- 跨模块API调用,通过控制反转来做组件解耦
路由库
1、目前市面上路由库有哪些?
- 阿里 ARouter
- Airbnb DeepLinkDispatch
- 天猫 统跳协议
- ActivityRouter
- OkDeepLink
设计方案
1、路由的设计方案需要涉及到哪些方面?
- 路由注册
- 路由查找
- 路由分发
- 动态替换
- 动态拦截
- 安全拦截
- 方法调用
- 结果返回
- Module接入不同app
路由注册
1、AndroidManifest的缺点
AndroidManifest里面的acitivity声明scheme码是不安全的(所有App都可以打开这个页面)
2、三种路由注册方式:
- 注解产生路由表,通过DispatchActivity转发
- AndroidManifest注册,将其export=fasle,但是再通过DispatchActivity转发Intent(天猫的做法),好处是路由查找都是系统调用,省掉了维护路由表的过程,但是AndroidManifest配置还是比较不方便
- 注解自动修改AndroidManifest,可以避免路由表汇总的问题:用自定义Lint扫描出注解相关的Activity,然后在processManifestTask后面修改Manifest
汇总路由表
1、APT存在的问题
- 使用Apt会造成每个module都要手动注册
- 因为APT是在javacompile任务前插入了一个task,所以只对自己的moudle处理注解
ARouter
1、ARouter的特点
- 支持直接解析标准URL进行跳转,并自动注入参数到目标页面中
- 支持多模块工程使用
- 支持添加多个拦截器,自定义拦截顺序
- 支持依赖注入,可单独作为依赖注入框架使用
- 支持InstantRun
- 支持MultiDex(Google方案)
- 映射关系按组分类、多级管理,按需初始化
- 支持用户指定全局降级与局部降级策略
- 页面、拦截器、服务等组件均自动注册到框架
- 支持多种方式配置转场动画
- 支持获取Fragment
- 完全支持Kotlin以及混编
基础入门
依赖添加
build.gradle(Module:app)
android {
defaultConfig {
....
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
}
dependencies {
....
// 替换成最新版本, 需要注意的是api要与compiler匹配使用,均使用最新版可以保证兼容
implementation 'com.alibaba:arouter-api:1.4.0'
annotationProcessor 'com.alibaba:arouter-compiler:1.2.0'
}
SDK初始化
在Application中进行ARouter SDK初始化,并且控制调试信息。
public class BaseApplication extends Application{
//ARouter debug开关:true-open;false-close
private boolean isDebugARouter = true;
@Override
public void onCreate() {
super.onCreate();
// 1.必须在init之前调用
if (isDebugARouter) {
// These two lines must be written before init, otherwise these configurations will be invalid in the init process
ARouter.openLog(); // Print log
ARouter.openDebug(); // Turn on debugging mode (If you are running in InstantRun mode, you must turn on debug mode! Online version needs to be closed, otherwise there is a security risk)
}
// 2.初始化
ARouter.init(BaseApplication.this); // As early as possible, it is recommended to initialize in the Application
}
}
路径统一管理
路径统一管理, 也可以不用该方式。
public class ARouterConstants {
//路径必须要最少是/xx/xx
public static final String ACTIVITY_URL_LOGIN= "/app/LoginActivity";
}
增加注解
//使用该注解,并且指明path。
@Route(path = ARouterConstants.ACTIVITY_URL_LOGIN)
public class LoginActivity extends AppCompatActivity{
}
发起路由操作
直接跳转或者携带参数。
// 1. 应用内简单的跳转(通过URL跳转在'进阶用法'中)
ARouter.getInstance().build(ARouterConstants.ACTIVITY_URL_LOGIN).navigation();
// 2. 跳转并携带参数
ARouter.getInstance().build(ARouterConstants.ACTIVITY_URL_LOGIN)
.withLong("key1", 666L)
.withString("key2", "888")
.withSerializable("key3", new ProfileBean())
.navigation();
混淆处理
添加混淆规则(如果使用了Proguard)
-keep public class com.alibaba.android.arouter.routes.**{*;}
-keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}
# 如果使用了 byType 的方式获取 Service,需添加下面规则,保护接口
-keep interface * implements com.alibaba.android.arouter.facade.template.IProvider
# 如果使用了 单类注入,即不定义接口实现 IProvider,需添加下面规则,保护实现
-keep class * implements com.alibaba.android.arouter.facade.template.IProvider
路由表自动加载
使用 Gradle 插件实现路由表的自动加载(在整个项目的build.gradle中添加)
apply plugin: 'com.alibaba.arouter'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.alibaba:arouter-register:1.0.2"
}
}
- 可选使用
- 该插件必须搭配 api 1.3.0 以上版本使用!
- 通过 ARouter 提供的注册插件进行路由表的自动加载(power by AutoRegister), 默认通过扫描 dex 的方式 进行加载通过 gradle 插件进行自动注册可以缩短初始化时间解决应用加固导致无法直接访问 dex 文件,初始化失败的问题,
基础用法
跳转到Activity
1、跳转到Activity
ARouter.getInstance().build(ARouterConstants.ACTIVITY_URL_LOGIN).navigation();
跳转到Fragment
2、跳转到Fragment
- 先获取到Fragment
- 在Activity中将该Fragment加载到容器中
//1. 获取到目标Fragment
Fragment fragment = (Fragment) ARouter.getInstance().build(ARouterConstants.FRGAMENT_URL).navigation();
//2. 在Activity中加载该Frgment
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container, fragment)
.commit();
进阶用法
监听路由操作/降级策略
1、监听路由操作, 回调相应方法
ARouter.getInstance()
.build(ARouterConstants.ACTIVITY_URL_HOST)
.navigation(MDActivity.this, new NavigationCallback() {
@Override
public void onFound(Postcard postcard) {
// 找到目标
}