Android徹底元件化—UI跳轉升級改造

格竹子發表於2017-12-26

得到Android元件化方案已經開源,參見Android元件化方案開源。方案的解讀文章是一個小的系列,這是系列的第四篇文章:

  1. Android徹底元件化方案實踐
  2. Android徹底元件化demo釋出
  3. Android徹底元件化-程式碼和資源隔離
  4. Android徹底元件化—UI跳轉升級改造

自從8月份得到元件化方案AndroidComponent開源以後,收到了很多朋友的評論或者私信,提出了很多有價值的意見和建議,一個比較集中的點就在於元件之間的UI跳轉不夠優雅。當時由於業務比較緊張,沒有時間來完善這塊,最近終於抽出時間把UI跳轉的功能進行了升級改造,期間也得到@leobert等大牛的鼎力支援以及ARouter等優秀方案的啟發,現在DDComponent新的UI跳轉功能已經發布了,歡迎大家使用。

##已實現功能

  1. 按元件區分host,增加URL的可讀性
  2. 自動註冊路由,不再需要手動編寫程式碼進行路由分發
  3. 按需載入,只有實際跳轉到某個元件是,該元件的路由表才會載入
  4. 自動生成路由表檔案,方便元件開發團隊之間呼叫
  5. 引數支援依賴注入,不需要編寫引數的解析程式碼

##URL結構 元件之間的UI跳轉是基於標準的URL來實現的,先簡單看一下URL的基本構成:

<scheme>://<host>/<path>?<query>
複製程式碼

這個是最簡單的一個模型,不過用於我們UI跳轉協議已經足夠了。下面是一個跳轉到分享頁面的例項:

DDComp://share/shareBook?bookName=Gone with the Wind
複製程式碼

結合我們的元件化框架,我們簡單講一下各部分的含義

(1)scheme對應的是DDComp,這個在DDComponent沒有限制,使用時可以自己自由設定,一般為了從應用外跳轉進來,會在manifest的入口Activity新增以下配置

<intent-filter>
    <data android:scheme="DDComp" />
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
複製程式碼

(2)host對應的是share。在元件化框架中,每個元件對應一個唯一的host,例如分享元件的host就是share,讀書元件的host是reader等等。

  • host是路由分發的第一級,根據host可以定位到每個元件。
  • host還可以對所有的路由URL進行一個分組,只有呼叫到該分組的路由的時候,組內的路由才會被載入進記憶體

(3)path對應的是shareBook。它對應的是具體的每個具體的頁面,例如shareBook對應就是ShareActivity。在一個元件之內,path是不能重複的

(4)query對應的是bookName=Gone with the Wind。它表示要跳轉到ShareActivity,需要傳入的引數,例如這裡需要傳入書的名字等。

下面我們就講一下如何使用DDComponent的UI跳轉新功能!

元件新增必要的依賴

在元件的build.gradle中新增依賴

annotationProcessor 'com.luojilab.ddcomponent:router-anno-compiler:1.0.0'
複製程式碼

同時新增

defaultConfig {
    javaCompileOptions {
        annotationProcessorOptions {
             arguments = [host: "share"]
        }
    }
}
複製程式碼

此處的"share"是跳轉URI中的host,每個元件需要設定不同的host。

註冊元件到UIRouter中

在元件的宣告週期類ApplicationLike中,新增註冊和反註冊程式碼

public class ShareApplike implements IApplicationLike {
    UIRouter uiRouter = UIRouter.getInstance();
    @Override
    public void onCreate() {
        uiRouter.registerUI("share");
    }
    @Override
    public void onStop() {
        uiRouter.unregisterUI("share");
    }
}
複製程式碼

目標頁面新增註解

首先在跳轉的目的Activity上新增RouteNode註解

@RouteNode(path = "/shareBook", desc = "分享書籍頁面")
public class ShareActivity extends AppCompatActivity {
複製程式碼

如果需要傳入引數,在具體的引數定義上增加Autowired註解:

@Autowired
String bookName;
@Autowired
Author author;
複製程式碼

注意此處的引數不能是private的,否則編譯會直接報錯。這裡的原因在於依賴注入的時候沒有使用反射,而是直接呼叫了該引數,所以需要引數至少是包可見的。

依賴注入

如果想使用自動裝載功能,需要在Activity的onCreate中呼叫方法

AutowiredService.Factory.getInstance().create().autowire(this);
複製程式碼

建議該方法在基類Activity中呼叫

build專案

專案執行build,會生成apt檔案,具體可在build目錄下面檢視 同時還會在根目錄生成UIRouterTable資料夾,裡面會列出每個元件向外提供的路由表

auto generated, do not change !!!! 

HOST : share

分享雜誌頁面
/shareMagazine
author:com.luojilab.componentservice.share.bean.Author
bookName:String

分享書籍頁面
/shareBook
author:com.luojilab.componentservice.share.bean.Author
bookName:String
複製程式碼

跳轉

在發起跳轉頁面,有三種方式可以跳轉到目的頁面

Bundle方式
    // UI transfer with Bundle
    private void goToShareActivityWithBundle() {
        Author author = new Author();
        author.setName("Margaret Mitchell");
        author.setCounty("USA");
        Bundle bundle = new Bundle();
        bundle.putString("bookName", "Gone with the Wind");
        bundle.putString("author", JsonService.Factory.getInstance()
                .create().toJsonString(author));
        UIRouter.getInstance().openUri(getActivity(), "DDComp://share/shareBook", bundle);
    }
複製程式碼
URI方式
    // UI transfer with URI
    private void goToShareActivityWithUri() {
        Author author = new Author();
        author.setName("Barack Obama");
        author.setCounty("New York");
        final String URI_LEGAL = "DDComp://share/shareMagazine?bookName=NYTIME&amp;author=";
        legal and illegal data delivering*/
        UIRouter.getInstance().openUri(getActivity(),
                URI_LEGAL
                        + JsonService.Factory.getInstance().create().toJsonString(author), null);
    }
複製程式碼
startActivityForResult
    //startActivityForResult
    private void goToShareActivityForResult() {
        Author author = new Author();
        author.setName("Margaret Mitchell");
        author.setCounty("USA");
        UIRouter.getInstance().openUri(getActivity(),
                "DDComp://share/shareBook?bookName=Gone with the Wind&amp;author="
                        + JsonService.Factory.getInstance().create().toJsonString(author), null, 7777);
    }
複製程式碼

具體使用請參見github原始碼

如果對方案有不理解的地方,歡迎閱讀解析文章Android徹底元件化方案實踐Android徹底元件化demo釋出

目前很多app已經使用ARouter來進行UI跳轉,DDComponent也是支援ARouter的,只是為了更契合現在的元件化框架,所以自己實現了一套。鑑於已使用ARouter的app遷移成本有點高,後面會專門寫一篇如何在元件化框架中使用ARouter的文章,敬請期待!

相關文章