1.前言
- 組件化或者模塊化開發模式,已逐漸成為熱浪的形式,使用這些模式可以讓我們程序更容易的擴展、更方便的維護
更快捷的同步開發與更簡單的單獨調試,而ARouter
的出現就是讓組件間、模塊間是實現完全的獨立。 -
ARouter
是:阿里巴巴自研路由框架,主要解決組件間、模塊間的 界面跳轉 問題。 - 今天用最簡單的方式講解Arouter的使用與原理。
- 文章中實例 linhaojian的Github
2.目錄
arouter目錄.png
3.簡介
arouter簡介.png
4.原理
4.1 關系分析
-
從A界面跳轉到B界面這個過程,我們看看arouter與界面間關系,如下圖:
arouter與界面關系.png - 1.注冊
B界面將類的信息,通過key-value的形式,注冊到arouter中。
- 2.查詢
A界面將類信息與額外信息(傳輸參數、跳轉動畫等),通過key傳遞至arouter中,并查詢對應需要跳轉類的信息。
- 3.結合
將A界面類信息、參數與B界面的類信息進行封裝結合。
- 4.跳轉
將結合后的信息,使用startActivity實現跳轉。
4.2 流程分析
-
A界面跳轉到B界面,arouter做了以下工作:
arouter流程.png
從上圖流程中,我們可以發現Arouter中原理:
1.通過apt技術利用注解編譯時生成類,封裝目標界面類的類信息。
2.在初始化時,把編譯生成的類通過key-value的方式存儲在arouter中。
3.發送操作者通過key獲取到目標界面類的信息。
4.把發送操作者的信息與目標界面類信息進行結合或者關聯在一起。
5.實現跳轉功能。
- 其實簡單概括:將需要相互跳轉的界面信息傳遞至arouter中存儲關聯 & 實現跳轉。
5.使用
5.1 跳轉界面不帶參
- 發送跳轉操作
// 1. 普通跳轉
ARouter.getInstance().build("/test/activity").navigation();
- 目標界面
// 在支持路由的頁面上添加注解(必選)
// 這里的路徑需要注意的是至少需要有兩級,/xx/xx
@Route(path = "/test/activity")
public class YourActivity extend Activity {
...
}
5.2 跳轉界面帶參
- 發送跳轉操作
ARouter.getInstance().build("/test/1")
.withLong("key1", 666L)
.withString("key3", "888")
.withSerializable("key4", new Test("Jack", "Rose"))
.navigation();
- 目標界面
@Route(path = "/test/1")
public class YourActivity extend Activity {
//獲取數據三種方式
//1.通過Autowired注解表明key & 需要在onCreate中調用ARouter.getInstance().inject(this);配合使用
@Autowired(name = "key1")
public long data;
//2.通過Autowired注解 & 將key1作為屬性的名稱 & 需要在onCreate中調用ARouter.getInstance().inject(this);配合使用
@Autowired()
public long key1;
//3.通過Bundle獲取
getIntent().getExtras().getLong("key1")
}
5.3 跳轉界面帶參(傳遞Object)
- 定義解析Obeject的SerializationService
/**
* 處理傳遞參數中自定義的Object---》withObject
*/
@Route(path = "/custom/json")
public class JsonSerializationService implements SerializationService {
Gson gson;
@Override
public <T> T json2Object(String input, Class<T> clazz) {
return gson.fromJson(input,clazz);
}
@Override
public String object2Json(Object instance) {
return gson.toJson(instance);
}
@Override
public <T> T parseObject(String input, Type clazz) {
return gson.fromJson(input,clazz);
}
@Override
public void init(Context context) {
gson = new Gson();
}
}
- 發送跳轉操作
ARouter.getInstance().build("/test/1")
.withObejct("key4", new Test("Jack", "Rose"))
.navigation();
- 目標界面
@Route(path = "/test/1")
public class YourActivity extend Activity {
...
SerializationService serializationService = ARouter.getInstance().navigation(SerializationService.class);
serializationService.init(this);
User obj = serializationService.parseObject(getIntent().getStringExtra("key4"), User.class);
}
5.4 Uri跳轉
- 界面配置
<activity android:name=".activity.SchameFilterActivity">
<!-- Schame -->
<intent-filter>
<data
android:host="m.aliyun.com"
android:scheme="arouter"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
- 發送跳轉操作
Uri testUriMix = Uri.parse("arouter://m.aliyun.com/test/activity2");
ARouter.getInstance().build(testUriMix)
.withString("key1", "value1")
.navigation();
- 目標界面
@Route(path = "/test/activity2")
public class Test2Activity extends AppCompatActivity {
}
5.5 跳轉結果監聽
ARouter.getInstance()
.build("/test/activity2")
.navigation(this, new NavCallback() {
@Override
public void onArrival(Postcard postcard) {
}
@Override
public void onInterrupt(Postcard postcard) {
Log.d("ARouter", "被攔截了");
}
});
5.6 聲明攔截器(攔截跳轉過程,面向切面編程)
// 比較經典的應用就是在跳轉過程中處理登陸事件,這樣就不需要在目標頁重復做登陸檢查
// 攔截器會在跳轉之間執行,多個攔截器會按優先級順序依次執行
@Interceptor(priority = 8, name = "測試用攔截器")
public class TestInterceptor implements IInterceptor {
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
...
callback.onContinue(postcard); // 處理完成,交還控制權
// callback.onInterrupt(new RuntimeException("我覺得有點異常")); // 覺得有問題,中斷路由流程
// 以上兩種至少需要調用其中一種,否則不會繼續路由
}
@Override
public void init(Context context) {
// 攔截器的初始化,會在sdk初始化的時候調用該方法,僅會調用一次
}
}
5.7 為目標頁面聲明更多信息
// 我們經常需要在目標頁面中配置一些屬性,比方說"是否需要登陸"之類的
// 可以通過 Route 注解中的 extras 屬性進行擴展,這個屬性是一個 int值,換句話說,單個int有4字節,也就是32位,可以配置32個開關
// 剩下的可以自行發揮,通過字節操作可以標識32個開關,通過開關標記目標頁面的一些屬性,在攔截器中可以拿到這個標記進行業務邏輯判斷
@Route(path = "/test/activity", extras = Consts.XXXX)
5.8 依賴注入解耦
- 注冊需要依賴注入的對象
@Route(path = "/provider/testP")
public class TestProvider implements IProvider {
@Override
public void init(Context context) {
}
public String test(){
return ("Hello Provider!");
}
}
- 獲取對象 & 使用
ARouter.getInstance().navigation(TestProvider.class).test();
6.總結
- 到此,
ARouter
就講解完畢。 - 如果喜歡我的分享,可以點擊 關注 或者 贊,你們支持是我分享的最大動力 。
- linhaojian的Github
歡迎關注linhaojian_CSDN博客或者linhaojian_簡書!
不定期分享關于安卓開發的干貨。
寫技術文章初心
- 技術知識積累
- 技術知識鞏固
- 技術知識分享
- 技術知識交流