自己動手,Android跨模塊頁面跳轉Router方案


在引入多模塊開發后,我們首先要解決的就是模塊間頁面跳轉的問題。本文意在提供一種思路而非框架。

為什么要使用Router

我們知道,Google SDK提供了顯式和隱式兩種原生路由方案。但在模塊化開發中,顯式Intent存在類直接依賴的問題,造成模塊間嚴重耦合。隱式Intent則需要在Manifest中配置大量路徑,導致難以拓展(如進行跳轉攔截)。為了解決以上問題,我們需要采用一套更為靈活的Router方案。

方案思路

我們的思路很簡單,使用注解,為每個activity類標注別名。在啟動時對類進行掃描,將帶有注解的activity存放路由表中。整個過程被我們封裝在ActionManager類中,并對外暴露startAction(String alias ,Bundle data)接口,跳轉時通過別名在路由表中進行匹配,完成跳轉。大致流程如下:

代碼實現

以下是我截取的代碼片段,方便大家理解,

  • 在創建Activity時,通過注解,為其注釋別名:
@Action("loginActivity ")
public class LoginActivity extends BaseBase{
        //代碼省略...
}
  • 在啟動時(Application類中),對包下的所有類進行掃描,將帶有注解標注的Activity,存入map,代碼如下:
private void activityScan(Context ctx) {
        try {
            //通過資源路徑獲得DexFile
            DexFile e = new DexFile(ctx.getPackageResourcePath());
            Enumeration entries = e.entries();
            //遍歷所有元素
            while(entries.hasMoreElements()) {
                String entryName = (String)entries.nextElement();
                //匹配Activity包名
                if(entryName.contains("activity")) {
                    //通過反射獲得Activity類
                    Class entryClass = Class.forName(entryName);
                    if(entryClass.isAnnotationPresent(Action.class)) {
                        Action action = (Action)entryClass.getAnnotation(Action.class);
                        this.mapping.put(action.value(), entryClass.getName());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
  • 對外暴露接口,提供根據別名跳轉Activity的方法:
ActionManager.getInstance().startAction(currentActivity.this ,"loginActivity ");

我們可以請求方法中做一些攔截處理,同樣可以通過Bundle傳輸數據。以下是startAction方法的實現:

public void startAction(Activity original, String alias) throws ClassNotFoundException {
        if(this.mapping.containsKey(alias)) {
            Intent intent = new Intent(original, Class.forName((String)this.mapping.get(alias)));
            original.startActivity(intent);
        } else {
            throw new ClassNotFoundException();
        }
}

我們通過這種方式,解決了跳轉Activity所產生的的模塊依賴問題,相較于原生方案,拓展性更強。但這種方案只是階段性的,還存在一些問題。首先,加載過程中,頻繁使用到反射,會產生性能問題。其次,對于每個Activity的別名,需要進行統一維護,增加了協作成本。對此,我們正在嘗試使用APT工具改進,目的是讓掃描過程在編譯期完成,避免運行時加載。

期望

目前市場上有不少Router框架,秉承不重復造輪子的原則,我們可以在項目中直接使用。但如開篇所述,我們意在提供一種思路,記錄演進過程,框架是別人的,思路是自己的,只有這樣才能形成對自己有益的技術棧。

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

推薦閱讀更多精彩內容