1. 程式人生 > >Android ARouter:最簡單&粗暴(使用與原理)講解

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

1.前言

  • 元件化或者模組化開發模式,已逐漸成為熱浪的形式,使用這些模式可以讓我們程式更容易的擴充套件、更方便的維護
    更快捷的同步開發與更簡單的單獨除錯,而ARouter的出現就是讓元件間、模組間是實現完全的獨立。
  • ARouter是:阿里巴巴自研路由框架,主要解決元件間、模組間的 介面跳轉 問題。
  • 今天用最簡單的方式講解Arouter的使用與原理。

2.目錄

arouter目錄.png

3.簡介

arouter簡介.png

4.原理

4.1 關係分析

  • 從A介面跳轉到B介面這個過程,我們看看arouter與介面間關係,如下圖:
    在這裡插入圖片描述
  • 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就講解完畢。
  • 如果喜歡我的分享,可以點選 關注 或者 ,你們支援是我分享的最大動力 。

不定期分享關於安卓開發的乾貨。

寫技術文章初心

  • 技術知識積累
  • 技術知識鞏固
  • 技術知識分享
  • 技術知識交流