一 、ARouter的配置
在对应的 build.gradle 文件中配置 ARouter 的相关依赖如下:
android {
defaultConfig {
...
//arouter start
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
//arouter end
}
}
dependencies {
// 替换成最新版本, 需要注意的是api
// 要与compiler匹配使用,均使用最新版可以保证兼容
//arouter start
implementation 'com.alibaba:arouter-api:1.5.0'
annotationProcessor 'com.alibaba:arouter-compiler:1.2.2'
annotationProcessor 'com.alibaba:arouter-annotation:1.0.6'
//arouter end
...
}
可以选择配置路由表自动加载,在项目下面的 build.gradle 文件中进行配置,配置方式如下:
apply plugin: 'com.alibaba.arouter'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.alibaba:arouter-register:1.0.2"
}
}
二、基础设置
- 打开日志并打印堆栈
ARouter.openLog();
- 开启调试模式(InstantRun需要开启
ARouter.openDebug();
- 初始化ARouter
// 初始化
// 调试模式不是必须开启,但是为了防止有用户开启了InstantRun,但是
// 忘了开调试模式,导致无法使用Demo,如果使用了InstantRun,必须在
// 初始化之前开启调试模式,但是上线前需要关闭,InstantRun仅用于开
// 发阶段,线上开启调试模式有安全风险,可以使用BuildConfig.DEBUG
// 来区分环境
ARouter.openDebug();
ARouter.init(getApplication());
- 关闭ARouter
ARouter.getInstance().destroy();
三、基础功能
- 简单的应用内跳转
只需要在要跳转的 Activity 上添加 @Route 注解即可,具体如下:
@Route(path = "/test/activity1", name = "测试用 Activity")
public class ActivityTest1 extends AppCompatActivity {
------
}
//跳转的地方调用
ARouter.getInstance().build("/test/activity1") .navigation();
- 普通跳转ForResult
startActivityForResult(new Intent(MainActivity.this,
ActivityFirst.class), 1);
public class ActivityFirst extends AppCompatActivity {
----------
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
Log.d(MainActivity.TAG,">>>>-ActivityFirst---requestCode="+requestCode+"--resultCode="+resultCode);
if (requestCode == 1 && resultCode == 4) {
Log.d(MainActivity.TAG,">>>>-ActivityFirst---");
String s=data.getStringExtra("bian");
textview.setText(s);
}
}
}
- 路由跳转ForResult
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
--------
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
Log.d(MainActivity.TAG,">>>>----requestCode="+requestCode+"--resultCode="+resultCode);
if (requestCode == 2 && resultCode == 6) {
String s=data.getStringExtra("key");
Log.d(MainActivity.TAG,">>>>-ActivityFirst---s="+s);
}
}
--------
}
ARouter.getInstance()
.build("/test/activity2")
.navigation(this, 2);
- 携带参数的应用内跳转
@Route(path = "/test/activity2")
public class ActivityTest2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test2);
String value = getIntent().getStringExtra("key1");
if (!TextUtils.isEmpty(value)) {
Toast.makeText(this, "exist param :" + value,
Toast.LENGTH_LONG).show();
}
Button finish=(Button) findViewById(R.id.quit);
finish.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(MainActivity.TAG,">>>>---ActivitySecond--");
Intent i=new Intent();
i.putExtra("key","result");
setResult(6,i);
finish();
}
});
}
}
// 调用的地方
ARouter.getInstance()
.build("/test/activity2")
.withString("key1", "value1")
.navigation();
- 获取Fragment实例
@Route(path = "/test/fragment")
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_blank, container, false);
}
}
//调用
Fragment fragment = (Fragment) ARouter.getInstance().build("/test/fragment").navigation();
- 旧版本转场动画
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();
}
四、进阶用法
- 通过URL跳转
@Route(path = "/test/webview")
public class TestWebview extends Activity {
WebView webview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_webview);
webview = (WebView) findViewById(R.id.webview);
webview.loadUrl(getIntent().getStringExtra("url"));
}
}
ARouter.getInstance()
.build("/test/webview")
.withString("url", "file:///android_asset/scheme-test.html")
.navigation();
在main/assets 放入目标html文件scheme-test.html
- 拦截器
@Route(path = "/test/activity4")
public class ActivityTest4 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test4);
((TextView)findViewById(R.id.test)).setText("I am " + ActivityTest4.class.getName());
String extra = getIntent().getStringExtra("extra");
if (!TextUtils.isEmpty(extra)) {
((TextView)findViewById(R.id.test2)).setText(extra);
}
}
}
//调用地方
ARouter.getInstance()
.build("/test/activity4")
.navigation(this, new NavCallback() {
@Override
public void onArrival(Postcard postcard) {
}
@Override
public void onInterrupt(Postcard postcard) {
Log.d("ARouter", "被拦截了");
}
});
- 依赖注入
@Route(path = "/test/activity_jnject", name = "测试用 Activity")
public class ActivityJnject extends AppCompatActivity {
@Autowired(desc = "姓名")
String name = "jack";
@Autowired
int age = 10;
@Autowired
int height = 175;
@Autowired(name = "boy", required = true)
boolean girl;
@Autowired
char ch = 'A';
@Autowired
float fl = 12.00f;
@Autowired
double dou = 12.01d;
@Autowired
TestSerializable ser;
@Autowired
TestParcelable pac;
@Autowired
TestObj obj;
@Autowired
List objList;
@Autowired
Map> map;
private long high;
@Autowired
String url;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_jnject);
ARouter.getInstance().inject(this);
String params = String.format(
"name=%s,\n age=%s, \n height=%s,\n girl=%s,\n high=%s,\n url=%s,\n ser=%s,\n pac=%s,\n obj=%s \n ch=%s \n fl = %s, \n dou = %s, \n objList=%s, \n map=%s",
name,
age,
height,
girl,
high,
url,
ser,
pac,
obj,
ch,
fl,
dou,
objList,
map
);
((TextView) findViewById(R.id.test)).setText("I am " + ActivityJnject.class.getName());
((TextView) findViewById(R.id.test2)).setText(params);
}
}
//调用部分
TestSerializable testSerializable = new TestSerializable("Titanic", 555);
TestParcelable testParcelable = new TestParcelable("jack", 666);
TestObj testObj = new TestObj("Rose", 777);
List objList = new ArrayList<>();
objList.add(testObj);
Map> map = new HashMap<>();
map.put("testMap", objList);
ARouter.getInstance().build("/test/activity_jnject")
// ARouter.getInstance().build("/test/activity1")
.withString("name", "老王")
.withInt("age", 18)
.withBoolean("boy", true)
.withLong("high", 180)
.withString("url", "https://a.b.c")
.withSerializable("ser", testSerializable)
.withParcelable("pac", testParcelable)
.withObject("obj", testObj)
.withObject("objList", objList)
.withObject("map", map)
.navigation();
这里有一个坑 报异常
object2Json(java.lang.Object)' on a null object reference
at com.alibaba.android.arouter.facade.Postcard.withObject(Postcard.java:230)
解决方案 必须自己实现一个类,用自己项目中的gson 或者fastjson
这里我选择的是第一种
@Route(path = "/service/json")
public class JsonServiceImpl implements SerializationService {
private Gson mGson;
@Override
public T parseObject(String input, Type clazz) {
checkJson();
return mGson.fromJson(input, clazz);
}
@Override
public void init(Context context) {
mGson = new Gson();
}
@Override
public T json2Object(String text, Class clazz) {
checkJson();
return mGson.fromJson(text, clazz);
}
@Override
public String object2Json(Object instance) {
checkJson();
return mGson.toJson(instance);
}
public void checkJson() {
if (mGson == null) {
mGson = new Gson();
}
}
}
如果项目中用的是fastjson 则这个文件定义为
@Route(path = "/yourservicegroupname/json")
public class JsonServiceImpl implements SerializationService {
@Override
public void init(Context context) {
}
@Override
public T json2Object(String text, Class clazz) {
return JSON.parseObject(text, clazz);
}
@Override
public String object2Json(Object instance) {
return JSON.toJSONString(instance);
}
@Override
public T parseObject(String input, Type clazz) {
return JSON.parseObject(input, clazz);
}
}
五、服务管理
需要定义一个接口类 实现 IProvider 与其实现类
public interface HelloService extends IProvider {
void sayHello(String name);
}
package com.haoran.arouterpro.testservice;
import android.content.Context;
import android.util.Log;
import android.widget.Toast;
import com.alibaba.android.arouter.facade.annotation.Route;
/**
* TODO feature
*
* @author Alex Contact me.
* @version 1.0
* @since 2017/1/3 10:26
*/
@Route(path = "/yourservicegroupname/hello")
public class HelloServiceImpl implements HelloService {
Context mContext;
@Override
public void sayHello(String name) {
Toast.makeText(mContext, "Hello " + name, Toast.LENGTH_SHORT).show();
}
/**
* Do your init work in this method, it well be call when processor has been load.
*
* @param context ctx
*/
@Override
public void init(Context context) {
mContext = context;
Log.e("testService", HelloService.class.getName() + " has init.");
}
}
- 调用服务ByName
((HelloService) ARouter.getInstance().build("/yourservicegroupname/hello").navigation()).sayHello("mike");
- 调用服务 ByType
ARouter.getInstance().navigation(HelloService.class).sayHello("mike");
- 调用单类
ARouter.getInstance().navigation(SingleService.class).sayHello("Mike");
六、多模块
- 跳转到模块1
@Route(path = "/module/1")
public class ActivityModule1 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_module1);
}
}
ARouter.getInstance().build("/module/1").navigation();
- 跳转到模块2
@Route(path = "/module/2", group = "m2")
public class ActivityModule2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_module2);
}
}
// 这个页面主动指定了Group名
ARouter.getInstance().build("/module/2", "m2").navigation();
七、降级策略
降级策略必须创建一个类 并实现 DegradeService接口,不然会有异常
ARouter::There is no route match the path
@Route(path = "/xx/xx")
public class DegradeServiceImpl implements DegradeService{
Context mContext;
@Override
public void onLost(Context context, Postcard postcard) {
}
@Override
public void init(Context context) {
this.mContext = context ;
}
}
- 跳转失败,单独降级
ARouter.getInstance().build("/xxx/xxx").navigation(this, new NavCallback() {
@Override
public void onFound(Postcard postcard) {
Log.d("ARouter", "找到了");
}
@Override
public void onLost(Postcard postcard) {
Log.d("ARouter", "找不到了");
}
@Override
public void onArrival(Postcard postcard) {
Log.d("ARouter", "跳转完了");
}
@Override
public void onInterrupt(Postcard postcard) {
Log.d("ARouter", "被拦截了");
}
});
- 跳转失败,全局降级
ARouter.getInstance().build("/xxx/xxx").navigation();
- 服务调用失败
ARouter.getInstance().navigation(MainActivity.class);
项目代码