配置:
build.grade中配置:
android {...defaultConfig {...javaCompileOptions {? ? ? ? ? ? annotationProcessorOptions {? ? ? ? ? ? ? ? arguments = [moduleName: project.getName()]? ? ? ? ? ? }? ? ? ? }? ? }dependencies {? compile'com.alibaba:arouter-api:1.2.2'annotationProcessor'com.alibaba:arouter-compiler:1.1.3'}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
初始化:
一般在Application.onCreate()的初始化:
if(isDebug()) {// 這兩行必須寫在init之前,否則這些配置在init過程中將無效ARouter.openLog();// 打印日志ARouter.openDebug();// 開啟調(diào)試模式(如果在InstantRun模式下運行,必須開啟調(diào)試模式!線上版本需要關(guān)閉,否則有安全風險)}ARouter.init(mApplication);// 盡可能早,推薦在Application中初始化
1
2
3
4
5
6
添加注解:
對于你需要路由到的Activity,需要使用Route注解,對于Route注解,必須初始化path路勁,而且path必須至少存在兩級以上,即像這樣 /xx/xx ….,例子如下:
@Route(path ="/simple/simple1Activity")publicclassSimple1ActivityextendsAppCompatActivity{}
1
2
3
路由該Activity時,使用一下方法:
ARouter.getInstance().build("/simple/simple1Activity").navigation();
1
最基本的路由方案已經(jīng)好了,現(xiàn)在編譯就可以使用了。沒錯,就是這么簡單。
路由傳遞參數(shù):
上面簡單的路由已經(jīng)完成了,如果需要需要想目標Activity傳遞參數(shù)呢?可以看下面的例子,先看路由命令:
ARouter.getInstance().build("/simple/simpledata").withString("name","zhangsan").withInt("age",18).withParcelable("test",newTestParcelable("Tom",12)).navigation();
1
2
3
4
5
6
那么目標Activity呢?源碼如下:
@Route(path ="/simple/simpledata")publicclassSimpleDataActivityextendsAppCompatActivity{TextView tv ;@Autowired()? ? String name ;@Autowired(name ="age")intage ;@AutowiredTestParcelable test ;@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);? ? ? ? setContentView(R.layout.activity_simple_data);//injectARouter.getInstance().inject(this);? ? ? ? tv = (TextView) findViewById(R.id.id_tv);? ? ? ? tv.setText("name:"+ name +",age:"+ age? +",test:"+test);? ? }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
我們需要為參數(shù)聲明字段,并用@Autowired注解表示,@Autowired可以填寫name標識,依次來映射URL中的不同參數(shù);最后使用ARouter.getInstance().inject(this);方法來inject來初始化@Autowired注解的字段。結(jié)果就就不貼了,這個比較簡單。
startActivityForResult方案:
很多時候我們路由到目標Activity,然后需要返回Result,即我們通常重寫的startActivityForResult&onActivityResult方法。使用ARouter也很簡單,如下:
ARouter.getInstance().build("/simple/simpledata").? ? ? ? ? ? ? ? withString("name","zhangsan").? ? ? ? ? ? ? ? withInt("age",18).? ? ? ? ? ? ? ? withParcelable("test",newTestParcelable("Tom",12)).? ? ? ? ? ? ? ? navigation(this,100);
1
2
3
4
5
只需要在navigation()方法中添加參數(shù)了,第一個參數(shù)必須是Activity,第二個參數(shù)就是我們的requestCode。
獲取路由結(jié)果:
當我們每一次進行路由時,可能需要知道我們的路由是否被接受,是否丟失,是否被攔截器攔截,那么可以使用navigation()方法的重載函數(shù):
ARouter.getInstance().build("/test/simple_interceptor").navigation(this,newNavCallback() {@OverridepublicvoidonArrival(Postcard postcard) {//路由到達之后調(diào)用Log.d("MainActivity","onArrival : "+ postcard.getPath());? ? ? ? ? ? }@OverridepublicvoidonInterrupt(Postcard postcard) {//路由被攔截時調(diào)用Log.d("MainActivity","onInterrupt : "+ postcard.getPath());? ? ? ? ? ? }@OverridepublicvoidonLost(Postcard postcard) {//路由被丟失時調(diào)用Log.d("MainActivity","onLost : "+ postcard.getPath());? ? ? ? ? ? }@OverridepublicvoidonFound(Postcard postcard) {//路由目標被發(fā)現(xiàn)時調(diào)用Log.d("MainActivity","onLost : "+ postcard.getPath());? ? ? ? ? ? }? ? ? ? });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
interceptor攔截器:
ARouter也添加了攔截器模式,攔截器有很多用處,比如路由到目標頁面時,檢查用戶是否登錄,檢查用戶權(quán)限是否滿足,如果不滿足,則路由到相應的登錄界面或者相應的路由界面。ARouter的攔截器比較奇葩,只需要實現(xiàn)IInterceptor接口,并使用@Interceptor注解即可,并不需要注冊就能使用。當然這也有了它的壞處,就是每一次路由之后,都會經(jīng)過攔截器進行攔截,顯然這樣程序的運行效率就會降低。Interceptor可以定義多個,比如定義登錄檢查攔截器,權(quán)限檢查攔截器等等,攔截器的優(yōu)先級使用priority定義,優(yōu)先級越大,越先執(zhí)行。攔截器內(nèi)部使用callback.onContiune()/callback.onInterrupt(),前者表示攔截器任務完成,繼續(xù)路由;后者表示終止路由。例子:
@Interceptor(priority =4)publicclassTestInterceptorimplementsIInterceptor{@Overridepublicvoidprocess(finalPostcard postcard,finalInterceptorCallback callback) {? ? ? ? Log.d("interceptor",postcard.getPath() +".."+ postcard.getGroup());//這里進行邏輯處理? //callback.onContinue(postcard);or//callback.onInterrupt(postcard)}@Overridepublicvoidinit(Context context) {? ? ? ? Log.d("init",TestInterceptor.class.getSimpleName() +" has been inited");? ? }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
而這里的邏輯判斷,比如我要判斷用戶是否登錄,如果登錄了,則放行,否則進行登錄路由。
if(Constant.isLogin()) {? ? callback.onContinue(postcard);}else {? ? callback.onInterrupt(null);ARouter.getInstance().build("/router/login").navigation();}
1
2
3
4
5
6
當然了,如果有些路由希望不經(jīng)過任何的攔截器,ARouter很貼心的給出了一個綠色通道函數(shù)供我們使用,使用greenChannel()時所有的Interceptor將失效:
ARouter.getInstance().build("/test/simple_interceptor").greenChannel().navigation();
1
自定義全局降級策略:
這個說的比較高大上,通俗一點講,就是如果我們的app全是Native寫的,如果有一天我們的隱性的Intent不能匹配所有的Activity時,我們的Activity就會報錯,更壞的結(jié)果就是會導致崩潰。而降級策略就是為了解決這個問題的,如果不存在這個路由,那么我們可以集中處理這些錯誤,比如返回到主頁面,或者也可以返回一個錯誤頁面。降級策略需要實現(xiàn)DegradeService接口,并且使用@Route注解來表明那些哪些路由需要被處理。降級策略可以有多個。舉個例子:
@Route(path ="/user/*")publicclassLoginDegradeServiceImplimplementsDegradeService{Context mContext;@OverridepublicvoidonLost(Context context, Postcard postcard) {//LogUtils.d("onLost:"+ postcard);? ? ? ? ARouter.getInstance().build("/router/login").navigation();? ? }@Overridepublicvoidinit(Context context) {this.mContext = context ;? ? }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
這個是定義登錄時,如果使用了錯誤的路由方式,將路由到登錄界面。注意到path=”/user/*”,表明只要是一次級的user的錯誤路由,都會傳遞到這里。因為項目會存在很多模塊,這里定義的”/user/” 只是識別用戶模塊的,而影響其他模塊。
服務管理:
個人感覺這個功能比較雞肋,項目中目前沒有用到過,但是ARouter還是提供了相應的方法,這里還是簡單介紹一下。這里的服務不是Android四大組件的所說的那種Service,更貼切的說,應該是一種接口,通過ARouter依賴注入找到其實現(xiàn)類,然后使用接口中的方法。?
服務接口需要繼承IProvider:
publicinterfaceHelloServiceextendsIProvider{voidsayHello(String name);? ? }
1
2
3
獲取實現(xiàn)類,并@Route綁定path:
@Route(path ="/service/helloservice")publicclassHelloServiceImplimplementsHelloService{Context mContext;@OverridepublicvoidsayHello(String name) {? ? ? ? Toast.makeText(mContext,"hello "+ name, Toast.LENGTH_SHORT).show();? ? }@Overridepublicvoidinit(Context context) {this.mContext = context ;? ? ? ? Log.d("HelloServiceImpl","the context is "+ mContext);? ? }}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
那么在使用時,可以有兩種方法,一種是通過Name獲取,一種是通過Type獲取:?
通過Name獲?。?/p>
((HelloService)ARouter.getInstance().build("/service/helloservice").navigation()).sayHello("micro name ");
1
而通過Type獲取時:
ARouter.getInstance().navigation(HelloService.class).sayHello("micro type ");
1
通過上述兩種方案,都可以調(diào)用HelloService接口,并執(zhí)行sayHello方法。個人感覺并沒什么卵用,我需要這種實現(xiàn)方案到底要干什么呢? 個人現(xiàn)在的項目還用不上這種方式吧。