框架地址:https://github.com/alibaba/ARouter
ARouter的个优势
一、功能介绍
支持直接解析标准URL进行跳转,并自动注入参数到目标页面中
支持多模块工程使用
支持添加多个拦截器,自定义拦截顺序
支持依赖注入,可单独作为依赖注入框架使用
支持InstantRun
支持MultiDex(Google方案)
映射关系按组分类、多级管理,按需初始化
支持用户指定全局降级与局部降级策略
页面、拦截器、服务等组件均自动注册到框架
支持多种方式配置转场动画
支持获取Fragment
完全支持Kotlin以及混编(配置见文末 其他#5)
支持第三方 App 加固(使用 arouter-register 实现自动注册)
二、典型应用
从外部URL映射到内部页面,以及参数传递与解析
跨模块页面跳转,模块间解耦
拦截跳转过程,处理登陆、埋点等逻辑
跨模块API调用,通过控制反转来做组件解耦
ARouter 配置
android {
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [ moduleName : project.getName() ]
}
}
}
}
dependencies {
implementation 'com.alibaba:arouter-api:1.3.1'
annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'
}
初始化SDK
public class AppApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
if (BuildConfig.DEBUG) {
ARouter.openLog();//打开日志
ARouter.openDebug();//打开调式模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
}
ARouter.init(this);
}
}
添加注解 发起路由操作
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
@Route(path = "/test/TestActivity")//添加路由注解 并且这里的路径需要注意的是至少需要有两级
public class TestActivity extends Activity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
findViewById(R.id.btn_click).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ARouter.getInstance().build("/test/TestActivity1");//发起无参数的路由操作
//ARouter.getInstance().build("/test/TestActivity1").navigation(TestActivity.this,0X123);//相当于startActivityForResult
}
});
findViewById(R.id.btn_click_params).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ARouter.getInstance().build("/test/TestActivity1").withString("name","xionglihui").navigation();//带参数
}
});
}
}
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.widget.TextView;
import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
@Route(path = "/test/TestActivity1")////添加路由注解 并且这里的路径需要注意的是至少需要有两级
public class TestActivity1 extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test1);
ARouter.getInstance().inject(this);
String namse = getIntent().getStringExtra("name");//获取参数
TextView txtName = (TextView) findViewById(R.id.txt_activity_test1);
txtName.setText(namse);
}
}
声明拦截器(拦截跳转过程,面向切面编程)
直接继承IInterceptor即可 登录拦截 实例
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import com.alibaba.android.arouter.facade.Postcard;
import com.alibaba.android.arouter.facade.annotation.Interceptor;
import com.alibaba.android.arouter.facade.callback.InterceptorCallback;
import com.alibaba.android.arouter.facade.template.IInterceptor;
import com.alibaba.android.arouter.launcher.ARouter;
// 比较经典的应用就是在跳转过程中处理登陆事件,这样就不需要在目标页重复做登陆检查
// 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行
@Interceptor(priority = 1,name = "登录拦截")
public class TestInterceptor implements IInterceptor {
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
String groups = postcard.getGroup();
if("needLogin".equals(groups)){
if(true) {//登录判断
Log.e("你需要登录", "你需要登录");
ARouter.getInstance().build("/login/LoginActivity").navigation();
callback.onInterrupt(null);
}
}else{
callback.onContinue(postcard);
}
}
@Override
public void init(Context context) {
Log.e("TestInterceptor","init");
}
}
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
@Route(path = "/needLogin/TestActivity")//添加路由注解 并且这里的路径需要注意的是至少需要有两级
public class TestActivity extends Activity{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
findViewById(R.id.btn_click_need).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ARouter.getInstance().build("/needLogin/TestActivity").navigation();//这个页面需要已登录状态才能进去
}
});
}
}
通过URL跳转
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import com.alibaba.android.arouter.launcher.ARouter;
// 新建一个Activity用于监听Schame事件,之后直接把url传递给ARouter即可
public class SchameFilterActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Uri uri = getIntent().getData();
ARouter.getInstance().build(uri).navigation();
finish();
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xiong.arouterapplication">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
<activity android:name=".SchameFilterActivity">
<intent-filter>
<data
android:host="com.xiong"
android:scheme="app" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
intent-filter>
activity>
<activity android:name=".WebViewActivity" />
application>
manifest>
package com.xiong.arouterapplication;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.View;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
@Route(path = "/test/MainActivity")
public class MainActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final String url= "file:///android_asset/test.html";
findViewById(R.id.btn_main_skip_wap).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ARouter.getInstance().build("/test/WebViewActivity").withString("url",url).withString("title","title").navigation();
}
});
}
}
package com.xiong.arouterapplication;
import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.webkit.WebView;
import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
// 为每一个参数声明一个字段,并使用 @Autowired 标注
// URL中不能传递Parcelable类型数据,通过ARouter api可以传递Parcelable对象
@Route(path = "/test/WebViewActivity")
public class WebViewActivity extends Activity {
@Autowired
public String title;
@Autowired
public String url;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ARouter.getInstance().inject(this);// ARouter会自动对字段进行赋值,无需主动获取
setContentView(R.layout.activity_webview);
WebView webView = findViewById(R.id.wbv_webview_acitivyt);
webView.loadUrl(url);
}
}
<html>
<title>测试AROUTEtitle>
<body>
<a href="app://com.xiong/test/WebViewActivity?title=hello&url=https://www.baidu.com/">app://com.xiong/test/WebViewActivitya>
br>
<a href="app://com.xiong/test/MainActivity">app://com.xiong/test/WebViewActivitya>
br>
body>
html>
详细的API说明
// 构建标准的路由请求
ARouter.getInstance().build("/home/main").navigation();
// 构建标准的路由请求,并指定分组
ARouter.getInstance().build("/home/main", "ap").navigation();
// 构建标准的路由请求,通过Uri直接解析
Uri uri;
ARouter.getInstance().build(uri).navigation();
// 构建标准的路由请求,startActivityForResult
// navigation的第一个参数必须是Activity,第二个参数则是RequestCode
ARouter.getInstance().build("/home/main", "ap").navigation(this, 5);
// 直接传递Bundle
Bundle params = new Bundle();
ARouter.getInstance().build("/home/main").with(params).navigation();
// 指定Flag
ARouter.getInstance().build("/home/main").withFlags();.navigation();
// 获取Fragment
Fragment fragment = (Fragment) ARouter.getInstance().build("/test/fragment").navigation();
// 对象传递
ARouter.getInstance().withObject("key", new TestObj("Jack", "Rose")).navigation();
// 觉得接口不够多,可以直接拿出Bundle赋值
ARouter.getInstance() .build("/home/main") .getExtra();
// 转场动画(常规方式)
ARouter.getInstance().build("/test/activity2").withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom).navigation(this);
// 转场动画(API16+)
ActivityOptionsCompat compat = ActivityOptionsCompat.makeScaleUpAnimation(v, v.getWidth() / 2,
v.getHeight() / 2, 0, 0);
// ps. makeSceneTransitionAnimation 使用共享元素的时候,需要在navigation方法中传入当前Activity
ARouter.getInstance().build("/test/activity2").withOptionsCompat(compat).navigation();
// 使用绿色通道(跳过所有的拦截器)
ARouter.getInstance().build("/home/main").greenChannel().navigation();
// 使用自己的日志工具打印日志
ARouter.setLogger();