Android ARouter:最簡單&粗暴(使用與原理)講解

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_簡書

不定期分享關于安卓開發的干貨。


寫技術文章初心

  • 技術知識積累
  • 技術知識鞏固
  • 技術知識分享
  • 技術知識交流
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容