转自,感谢原作者。怕原文失效,所以内容也拷过来了
ARouter简介
ARouter是阿里巴巴开源的Android平台中对页面、服务提供路由功能的中间件,提倡的是简单。它干的活就是负责页面跳转的,看到这就有点纳闷,这Android不是有startActivity和startActivityForResult吗?
它的意义在哪呢?
ARouter的意义
- 灵活性强
在一些复杂的业务场景下,很多功能都是动态配置的,比如跳转到一个活动页面,我们事先并不知道具体的目标页面,但如果事先做好了约定,提前做好页面映射,便可以自由配置。 - 解耦
ARouter可以降低各个关联页面之间的耦合性,解耦页面之间的依赖关系。 - 简化代码
ARouter它是基于注解实现,使用方便,你之前的数行跳转代码可以精简成一行代码 - 性能优良
ARouter是在编译期处理注解的,对运行时性能没有影响 - 支持注解Fragment
ARouter不仅支持注解Activity,还支持注解Fragment
OK,好处意义讲到这里就可以了,赶紧把它引入到项目中吧
集成ARouter
- 在项目级的build.gradle中加入依赖:
buildscript {
repositories {
jcenter()
}
dependencies {
compile 'com.alibaba:arouter-api:1.3.1'
annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'
}
}
Api 的版本和 compiler 的版本号需要用最新的。最新的版本在 Github上可以找到。
[图片上传失败...(image-20b7a5-1541644404816)]
- ARouter初始化
Router需要初始化,用于初始化路由表,建议放到Application中做:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// 打印日志
ARouter.openLog();
// 开启调试模式(如果在InstantRun(就是AndroidStudio2.0以后新增的一个可以减少很多编译时间的运行机制)模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
ARouter.openDebug();
// 初始化尽可能早,推荐在Application中初始化
ARouter.init(this);
}
}
OK,集成完毕,开始使用!
使用基本ARouter
- ARouter注解路由
我们新建一个TestARouterActivity作为测试 ,在 TestARouterActivity中添加注解的代码如下:
// 在支持路由的页面上添加注解(必须写)
// 这里的路径需要注意的是至少需要有两级,/xx/xx,名字你自己起
@Route(path = "/com/TestARouterActivity")
public class TestARouterActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
}
}
- 开始跳转
//这里的"/com/TestARouterActivity"就是上面的TestARouterActivity添加的路由注解
ARouter.getInstance().build("/com/TestARouterActivity").navigation();
OK,跳转完成了,简单吧,哈哈
再来看一下稍微复杂一点的跳转:startActivityForResult()
这个就改动一处即可,其他不用变:
navigation(Activity mContext, int requestCode)
把上面的TestARouterActivity用来实现就是:
ARouter.getInstance().build("/com/TestARouterActivity").navigation(this , 100);
这里补充一点哈,如果你的路径下的对不上号,就是你想跳转到的页面的ARouter注解路由和build(" ")里面的不同,那么ARouter就是Toast提示,崩溃是不存在的。
再来看一下稍微复杂一点的跳转:页面传值
ARouter里面提供了丰富大量的参数类型,供我们选择
//基础类型
.withString( String key, String value )
.withBoolean( String key, boolean value)
.withChar( String key, char value )
.withShort( String key, short value)
.withInt( String key, int value)
.withLong( String key, long value)
.withDouble( String key, double value)
.withByte( String key, byte value)
.withFloat( String key, float value)
.withCharSequence( String key, CharSequence value)
//数组类型
.withParcelableArrayList( String key, ArrayList extends Parcelable > value)
.withStringArrayList( String key, ArrayList value)
.withIntegerArrayList( String key, ArrayList value)
.withSparseParcelableArray( String key, SparseArray extends Parcelable> value)
.withCharSequenceArrayList( String key, ArrayList value)
.withShortArray( String key, short[] value)
.withCharArray( String key, char[] value)
.withFloatArray( String key, float[] value)
.withCharSequenceArray( String key, CharSequence[] value)
//Bundle 类型
.with( Bundle bundle )
//Activity 跳转动画
.withTransition(int enterAnim, int exitAnim)
//其他类型
.withParcelable( String key, Parcelable value)
.withParcelableArray( String key, Parcelable[] value)
.withSerializable( String key, Serializable value)
.withByteArray( String key, byte[] value)
.withTransition(int enterAnim, int exitAnim)
比如我想给TestARouterActivity传递一个“哈哈哈”, key = "aaa", value = "哈哈哈",直接上代码:
ARouter.getInstance()
.build("/com/TestARouterActivity")
.withString("aaa", "哈哈哈")
.navigation();
而我们只需要在TestARouterActivity 类里面注解一下获取:
@Route(path = "/com/TestARouterActivity")
public class TestARouterActivity extends AppCompatActivity {
@Autowired(name = "aaa")
public String mTestVaule;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
}
}
OK,到这里,我们平时用到的Activity之间跳转的基本功能差不多都实现了,再来看点进阶的:
使用进阶ARouter
- 监听ARouter过程
在路由跳转的过程中,我们可以监听路由的过程,来观察我们的跳转是成功了还是失败了。
navigation(Context context, NavigationCallback callback)
NavigationCallback看名字就是到是个回调,我们就是通过它来知道跳转的结果怎么样了。NavigationCallback 的源码如下:
public interface NavigationCallback {
/**
* Callback when find the destination.
* 找到了
* @param postcard meta
*/
void onFound(Postcard postcard);
/**
* Callback after lose your way.
* 找不到了
* @param postcard meta
*/
void onLost(Postcard postcard);
/**
* Callback after navigation.
* 跳转完了
* @param postcard meta
*/
void onArrival(Postcard postcard);
/**
* Callback on interrupt.
* 被拦截了
* @param postcard meta
*/
void onInterrupt(Postcard postcard);
}
简单易用:
ARouter.getInstance()
.build("/com/TestARouterActivity")
.navigation(this, new NavCallback() {
@Override
public void onFound(Postcard postcard) {
Log.e("eeeee", "找到TestARouterActivity!");
}
@Override
public void onLost(Postcard postcard) {
Log.e("eeeee", 找不到TestARouterActivity!");
}
@Override
public void onArrival(Postcard postcard) {
Log.e("eeeee", "TestARouterActivity跳转完了!");
}
@Override
public void onInterrupt(Postcard postcard) {
Log.e("eeeee", "TestARouterActivity被拦截了!");
}
});
- ARouter的分组
现在去看下我们之前怎么注解的TestARouterActivity的路由
@Route(path = "/com/TestARouterActivity")
解析一下这个path:
在path这个字符串里面,”com” 就代表路由分组的标识,“TestARouterActivity” 代表是TestARouterActivity类的标识。组的标识和类的标识都可以自己定义的,需要记住的是组标识和类标识之间用斜杠来区分 ”\”
那什么是组呢?
ARouter框架是分组管理,按需加载
解释起来就是,在程序的编译期ARouter扫描了所有的注册页面、服务、字段、拦截器...,那么在程序的运行期就不能一股脑全部加载进来,这样就会一次性加载太多东西。所以ARouter就用分组来管理。
ARouter在初始化的时候只会一次性地加载所有的Root结点,而不会加载任何一个Group结点,这样就会极大地降低初始化时加载结点的数量。
通俗点说吧,比如你把TestARouterActivity1,TestARouterActivity2,TestARouterActivity3分成一组(分组的标识是一样的),组名比如叫"com"。ARouter初始化的时候不会加载"com"这个Group结点,一旦你需要跳到TestARouterActivity3这个页面了,那么ARouter才会再将com这个组加载进来。
- ARouter的自定义分组
ARouter的分组可以自定义,我们创建一个TestARouterActivity2并且添加 ARouter注解,指定它的自定义路由分组。如下所示:
@Route(path = "/com/TestARouterActivity2" , group = "testGroup")
public class TestARouterActivity2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_group);
}
}
上面代码中的"testGroup"就是TestARouterActivity2的自定义分组,如果我们不指定group字段,那么TestARouterActivity2的默认分组就是 "/ /"中间的"com"。我们可以代码验证一下:
@Route(path = "/com/TestARouterActivity2")
public class TestARouterActivity2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_group);
}
}
····
ARouter.getInstance()
.build("/com/TestARouterActivity2")
.navigation(this, new NavCallback() {
@Override
public void onArrival(Postcard postcard) {
Log.e("eeeee", "默认分组: " + postcard.getGroup());
}
});
上面代码打印的结果就是 默认分组:com
自定义分组我们怎么跳转呢?
很简单,自定义分组,发起路由:第二个参数就是路由的分组
build(String path, String group);
····
ARouter.getInstance().build("/com/TestARouterActivity2", "testGroup").navigation();
- 关闭ARouter
借用文档上的说明:关闭路由,这个操作慎用
ARouter.getInstance().destroy();
ARouter - Fragment
在Fragment中使用ARouter,和Activity中使用没多少差别
首先,创建 Fragment 类,并且添加路由注解
@Route(path = "/com/TestARouterFragment")
public class TestARouterFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_test, container, false);
return view;
}
}
然后,获取你的TestARouterFragment实例:
TestARouterFragment fragment = (TestARouterFragment)ARouter.getInstance().build( "/com/TestARouterFragment" ).navigation();
拿到了你的Fragment,然后该咋用就咋用
ARouter的混淆说明
-keep public class com.alibaba.android.arouter.routes.**{*;}
-keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}