版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lib739449500/article/details/97891938
传统跳转方式
第一种,通过intent跳转
以下主要针对下面1.4.1版本使用,不是github最新版本哦。
api "com.alibaba:arouter-api:1.4.1"
annotationProcessor "com.alibaba:arouter-compiler:1.2.2"
android {
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
}
// 在支持路由的页面上添加注解(必选)
// 这里的路径需要注意的是至少需要有两级,/xx/xx
@Route(path = "/test/activity")
public class YourActivity extend Activity {
...
}
if (isDebug()) { // 这两行必须写在init之前,否则这些配置在init过程中将无效
ARouter.openLog(); // 打印日志
ARouter.openDebug(); // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
}
ARouter.init(mApplication); // 尽可能早,推荐在Application中初始化
最好在Application中掉一下destroy方法。解绑,释放资源
@Override
public void onTerminate() {
Log.d("Application", "onTerminate");
super.onTerminate();
ARouter.getInstance().destroy();
}
// 1. 应用内简单的跳转(通过URL跳转在'进阶用法'中)
ARouter.getInstance().build("/test/activity").navigation();
// 2. 跳转并携带参数
ARouter.getInstance().build("/test/1")
.withLong("key1", 666L)
.withString("key3", "888")
.withObject("key4", new Test("Jack", "Rose"))
.navigation();
-keep public class com.alibaba.android.arouter.routes.**{*;}
-keep public class com.alibaba.android.arouter.facade.**{*;}
-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
apply plugin: 'com.alibaba.arouter'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.alibaba:arouter-register:?"
}
}
可选使用,通过 ARouter 提供的注册插件进行路由表的自动加载(power by AutoRegister), 默认通过扫描 dex 的方式 进行加载通过 gradle 插件进行自动注册可以缩短初始化时间解决应用加固导致无法直接访问 dex 文件,初始化失败的问题,需要注意的是,该插件必须搭配 api 1.3.0 以上版本使用!
在 Android Studio 插件市场中搜索 ARouter Helper
, 或者直接下载文档上方 最新版本
中列出的 arouter-idea-plugin
zip 安装包手动安装,安装后 插件无任何设置,可以在跳转代码的行首找到一个图标 () 点击该图标,即可跳转到标识了代码中路径的目标类
Uri uri=Uri.parse("/path/bactivity");
ARouter.getInstance().build(uri).navigation();
PS: Uri.parse的时候,改为完整路径也是支持的,例如改为val uri = Uri.parse(“tpnet://m.aliyun.com/path/bactivity”),也可以成功跳转到BActivity
Url跳转就是可以根据url来跳转,可以从网页跳到Activity
public class SchameFilterActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Uri uri = getIntent().getData();
ARouter.getInstance().build(uri).navigation();
finish();
}
}
该Activity的manifest为:
然后定义你要跳转到的Activity,这里定义一个UrlTargetActivity (记得在Manifest说明):
@Route(path = ARouterConstant.ACTIVITY_test_activity1)
public class UrlTargetActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_url_target);
TextView tv=findViewById(R.id.textView4);
tv.setText("当前页面是:"+getLocalClassName());
}
}
然后在手机打开一个网页,网页内容为:
arouter://m.aliyun.com/test/activity1
点击了这个网页链接之后,就到根据"arouter://m.aliyun.com(scheme://host)跳转到SchemeFilterActivity这个Activity,然后在这个Activity利用ARouter 根据path = test/activity1跳转到UrlTargetActivity
带参数的跳转是很常见的功能,Android可以通过Bundle去传递参数,如果使用ARouter框架,它传递参数通过以下去操作:
ARouter传递对象的时候,首先该对象需要Parcelable或者Serializable序列化,可能Parcelable这个序列化大家觉得手写起来比较麻烦,但是Android Studio已经有一些插件帮我们自动生成Parcelable序列化了(因为Android用Parcelable序列化优势会更加明显一些)
字符串、char、int等基本数据类型当然都是可以传递的 当然,它也可以直接传Bundle、数组、列表等很多对象,传递类型如下图
携带参数的界面跳转,简单使用如下图
其中,第一个参数代表的是参数的key,第二个参数对应的是我们要传递的属性值,也就是value
那么目标界面如何获取传递过来的值?
这个时候,我们需要在目标界面,使用Autowired注解,
PS:注意属性名字命名。所以为了规避每一个可能会遇到的风险,建议在@Autowired里面 都写上与之对应具体的key名。
直接调用withTransition,里面传入两个动画即可(R.anim.xxx)
Fragment的跳转也可以参照Activity跳转,第一步依旧是先写上类注释,然后是强转,代码如下
拦截器的意思是,例如你想在 AActivity跳到BActivity,如果有拦截器,就可以把这个过程拦截下来,做一些处理(禁止跳转、修改参数)。
拦截器使用和Activity@Route
差不多,只不过拦截器是使用另外一个注解@Interceptor
。有两个变量,priority是拦截器的优先级,值越小优先级越高,会优先拦截。name是拦截器的名称,开发也不怎么用。
添加拦截器的方法是利用Interceptor
注解,实现IInterceptor
接口。例如我添加一个拦截器:
/ 比较经典的应用就是在跳转过程中处理登陆事件,这样就不需要在目标页重复做登陆检查
// 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行
@Interceptor(priority = 8, name = "测试用拦截器")
public class TestInterceptor implements IInterceptor {
@Override
public void init(Context context) {
// 拦截器的初始化,会在sdk初始化的时候调用该方法,仅会调用一次
Log.e("arouterinterceptor", "拦截器初始化");
}
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
if (!TextUtils.isEmpty(postcard.getPath())
&& postcard.getPath().equals("/path/bactivity")) {
postcard.withString("extra", "我是在拦截器中附加的参数");
}
if(callback!=null){
callback.onContinue(postcard);
}
//终止跳转
//callback.onInterrupt(null)
//抛出异常
// callback.onInterrupt(RuntimeException("我觉得有点异常"))
// onContinue和onInterrupt至少需要调用其中一种,否则不会继续路由
}
}
在拦截器实现类使用注解@Interceptor
会自动注册,就是在编译期间会自动生成映射关系类,使用到的就是APT技术
这里因为是自动注册的,所以可以将不同功能的拦截器放在不同功能的模块中,只有模块被打包到整个项目中,因为自动注册机制所以拦截器就会生效,如果不将这些拦截器放到模块并打包到项目中,那就不会生效,这样就不用去做很多注册与反注册的工作,这也是ARouter适用于模块开发的原因之一。
这种应用场景也是很常见的,那ARouter该如何实现?
第一步:为了方便看效果,我们在第一个Activity设置requestCode 为123,
onActivityResult
第二步:需要在跳转的navigation方法(这是一个方法重载)里面的第二个参数,设置我们定义的requestCode,(通过匹配requestCode 来实现该功能)
第三步:在第二个界面的setResult方法里面,写上对应的resultCode,这里就不展示Intent数据了
综合上面三个步骤,项目编译运行,跳转到第二个界面然后返回上一个界面,日志成功打印: