Arouter 使用(一):
官方git: https://github.com/alibaba/ARouter/blob/master/README_CN.md
一、Arouter 简介:
1、功能介绍
- 支持直接解析标准URL进行跳转,并自动注入参数到目标页面中
- 支持多模块工程使用
- 支持添加多个拦截器,自定义拦截顺序
- 支持依赖注入,可单独作为依赖注入框架使用
- 支持InstantRun
- 支持MultiDex(Google方案)
- 映射关系按组分类、多级管理,按需初始化
- 支持用户指定全局降级与局部降级策略
- 页面、拦截器、服务等组件均自动注册到框架
- 支持多种方式配置转场动画
- 支持获取Fragment
- 完全支持Kotlin以及混编(配置见文末 其他#5)
- 支持第三方 App 加固(使用 arouter-register 实现自动注册)
- 支持生成路由文档
- 提供 IDE 插件便捷的关联路径和目标类
2、使用场景:
- 从外部URL映射到内部页面,以及参数传递与解析
- 跨模块页面跳转,模块间解耦
- 拦截跳转过程,处理登陆、埋点等逻辑
- 跨模块API调用,通过控制反转来做组件解耦
二、Arouter 使用
2.1 ARouter 集成
添加依赖和配置
defaultConfig {
minSdkVersion Integer.parseInt(MIN_SDK_VERSION)
targetSdkVersion Integer.parseInt(TARGET_SDK_VERSION)
versionName "0.0.1"
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName(), AROUTER_GENERATE_DOC: "enable"] //AROUTER_GENERATE_DOC 是否生成路由文档
}
}
}
dependencies {
// 替换成最新版本, 需要注意的是api
// 要与compiler匹配使用,均使用最新版可以保证兼容
compile 'com.alibaba:arouter-api:x.x.x'
annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'
}
2.2 Arouter 基本设置
初始化Arouter:
if (isDebug()) {// 这两行必须写在init之前,否则这些配置在init过程中将无效
ARouter.openLog();// 打印日志
ARouter.openDebug(); // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
}
ARouter.init(mApplication); // 尽可能早,推荐在Application中初始化
添加路由注解:
// 在支持路由的页面上添加注解(必选)
// 这里的路径需要注意的是至少需要有两级,/xx/xx
@Route(path = "/test/activity1", name = "测试用 Activity")
public class Test1Activity extends AppCompatActivity {
}
2.3 跳转
使用 ARouter 时这里使用了3个比不可少的类:
ARouter:
Postcard :
-
应用内跳转
ARouter.getInstance().build("/test/activity2").navigation();
当前 activity 名为 Test1Activity, 在当前activity 发起跳转请求 ,在build 中传入了一个地址
"/test/activity2 " ,此时 目标activity 必须 进行路由注解配置:
//path 对应的value 值 至少为2级 @Route(path = "/test/activity2", name = "测试用 Activity")
-
跳转到Kotlin 页面
ARouter.getInstance() .build("/kotlin/test") .withString("name", "老王") .withInt("age", 23) .navigation();
此时携带了参数,".withString(\"name\", \"老王\") " ," .withInt("age", 23) " 注意携带的参数指定了类型需要在目标Activity 定义向对应的类型字段来接收:
@Autowired :用来修饰目标activity 接收 来源Activity 传过来指定的 value
注意 :使用 @Autowired 来标记接收的value 值,需要在目标 Activity 调用
ARouter.getInstance().inject(this);//启用@Autowired 注释标记 一般在界面创建时进行注入
-
跳转ForResult
ARouter.getInstance().build("/test/activity2").navigation(this, 666);
navigation 几个构造方法:
//无参构造,通常在Activity使用,使用的上下文对象是 application public Object navigation() { return navigation(null); } //传入 context 上下文对象 public Object navigation(Context context) { return navigation(context, null); } // context 传入的上下文对象 //NavigationCallback 跳转结果处理 public Object navigation(Context context, NavigationCallback callback) { return ARouter.getInstance().navigation(context, this, -1, callback); } //mContext Activity 对象 // requestCode 相当于 startActivityForResult(intent,reqeuestCode) 中 reqeuestCode public void navigation(Activity mContext, int requestCode) { navigation(mContext, requestCode, null); } // mContext Activity //requestCode 相当于 startActivityForResult(intent,reqeuestCode) 中 reqeuestCode // NavigationCallback 处理跳转结果 public void navigation(Activity mContext, int requestCode, NavigationCallback callback) { ARouter.getInstance().navigation(mContext, this, requestCode, callback); }
在跳转到目标Activity 使用 Postcard 带有 requestCode 的构造方法,处理方法同 activity.startActivityForResult(Intent,requestCode)
-
自定义scheme 进行跳转
自定义Scheme 通过跳转通常是通过网页链接来跳转开打开我们客户端,自定义scheme 的格式通常是:
<a href = "arouter://xxx.xxx.com[主机名]/path[应用内部配置的router-path]"></a> 如: <a href= "arouter://m.aliyun.com/test/activity1">scheme跳转</>
注意: 目标activity 需要配置
1、@Route(path = "/test/activity1")
2、需要配置 intentFilter:
<!-- Scheme --> <intent-filter> <data android:host="m.aliyun.com" android:scheme="arouter"/> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.BROWSABLE"/> </intent-filter>
-
组件化跳转(module)
1、创建module_new
2、在 相应的module_new中添加相关配置:
defaultConfig { minSdkVersion Integer.parseInt(MIN_SDK_VERSION) targetSdkVersion Integer.parseInt(TARGET_SDK_VERSION) versionName "0.0.1" javaCompileOptions { annotationProcessorOptions { arguments = [AROUTER_MODULE_NAME: project.getName(), AROUTER_GENERATE_DOC: "enable"] //AROUTER_GENERATE_DOC 是否生成路由文档 } } } implementation 'com.alibaba:arouter-api:1.5.0' annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'
3、在 module_new 创建activity:例如:ModuleOneActivity
4、添加路由配置:
@Route(path = "/module_one/ModuleOneActivity") public class ModuleOneActivity extends AppCompatActivity {}
5、添加跳转代码
ARouter.getInstance().build("/module_one/ModuleOneActivity").navigation();
-
获取fragment 实例
.navigation() 方法会返回一个实例 进行转换
2.4 动画
-
转场动画
- 旧版本转场动画
ARouter.getInstance() .build("/test/activity2") //添加动画 .withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom) .navigation(this);
- 新版本转场动画
if (Build.VERSION.SDK_INT >= 16) { ActivityOptionsCompat compat = ActivityOptionsCompat.makeScaleUpAnimation(v, v.getWidth() / 2,v.getHeight() / 2, 0, 0); ARouter.getInstance() .build("/test/activity2") //添加动画 .withOptionsCompat(compat) .navigation(); } else { Toast.makeText(this, "API < 16,不支持新版本动画", Toast.LENGTH_SHORT).show(); }
2.5 拦截器
1、拦截器定义
拦截器用@Interceptor(priority = 7) 注释 如果有多个拦截器 拦截器按照顺序执行
@Interceptor(priority = 7)
public class TestInterceptor implements IInterceptor {
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
//继续分发
callback.onContinue(postcard);
//拦截
callback.onInterrupt(null);
//可以修改postcard 参数
// postcard.方法
}
@Override
public void init(Context context) {
Log.i("grage","TestInterceptor");
}
}
2.6 调用服务
Arouter 调用服务首先需要暴露一个 Service 的接口 :
public interface IMyService1 extends IProvider {
void startService();
}
定义Service 实现接口 IMyService1:
@Route(path = "/test/service2")
public class Service2 implements IMyService1 {
@Override
public void init(Context context) {
}
@Override
public void startService() {
Log.i("grage","startService");
}
}
-
ByName
Service2 navigation = (Service2) ARouter.getInstance().build("/test/service2").navigation(); navigation.startService();
-
ByType
ARouter.getInstance().navigation(IMyService1.class).startService();
-
调用单类
@Route(path = "/yourservicegroupname/single") //必须添加 public class SingleService implements IProvider { @Override public void init(Context context) { } public void log(){ Log.i("grage","SingleService"); } }
SingleService navigation = ARouter.getInstance().navigation(SingleService.class); navigation.log();
预处理服务:
@Route(path = "/servcice/pretreatmentServiceImpl")
public class PretreatmentServiceImpl implements PretreatmentService {
@Override
public boolean onPretreatment(Context context, Postcard postcard) {
Log.i("grage","PretreatmentServiceImpl");
//todo 跳转前预处理,如果需要自行处理跳转,该方法返回 false 即可
return false;
}
@Override
public void init(Context context) {
}
}
如果返回false 那么启动服务 目标service build.navigation 返回对象为null
2.8 资源销毁
ARouter.getInstance().destroy();
补充自定义传值:
// 如果需要传递自定义对象,新建一个类(并非自定义对象类),然后实现 SerializationService,并使用@Route注解标注(方便用户自行选择序列化方式),例如:
@Route(path = "/yourservicegroupname/json")
public class JsonServiceImpl implements SerializationService {
@Override
public void init(Context context) {
}
@Override
public <T> T json2Object(String text, Class<T> clazz) {
return JSON.parseObject(text, clazz);
}
@Override
public String object2Json(Object instance) {
return JSON.toJSONString(instance);
}
}