Router解決跨模組下的頁面跳轉樣本,router跳轉

來源:互聯網
上載者:User

Router解決跨模組下的頁面跳轉樣本,router跳轉

一、前言

開始模組化開發項目之後,一個很重要的問題就是頁面見的跳轉問題。

關於模組化發開,可詳見我的另一片文章 Android模組化開發探索 。

正是由於將項目模組化拆分,各模組之間沒有任何依賴關係,也互相不可見,那麼從A模組的a介面跳轉到B模組的b介面該怎麼辦呢?

二、跨模組跳轉的方法

這裡我們會先介紹這幾種常見的跳轉方法:

  1. 顯示跳轉
  2. 隱示跳轉
  3. Scheme協議跳轉
  4. Router路由表方案

2.1 顯示跳轉

顯示跳轉即我們最最常用的跳轉方法:使用Intent,傳入當前Activity上下文,和目標Activity的class對象即可,如下:

Intent intent = new Intent();intent.setClass(mContext, GuideActivity.class);startActivity(intent);

顯然,這種方法只能是目標Activity可見(Activity在同一個Module下)的時候才可以這樣調用。不適合跨模組間的跳轉。

2.2 隱示跳轉

我們這裡說的隱示跳轉,intent不設定class,而是設定Action或者Category。

例如:

在資訊清單檔中

<!--網頁展示介面--><activity  android:name="com.whaty.base.BaseWebViewActivity"  android:hardwareAccelerated="true">    <intent-filter>      <category android:name="android.intent.category.DEFAULT" />      <action android:name="com.whaty.base.BaseWebViewActivity" />    </intent-filter></activity>

跳轉時:

//建立一個隱式的 Intent 對象:Action 動作 Intent intent = new Intent(); //設定 Intent 的動作為清單中指定的action intent.setAction("com.whaty.base.BaseWebViewActivity"); startActivity(intent);

2.3 scheme跳轉

如果我們為 B 頁面定義一個 URI - wsc://home/bbb,然後把共用的 messageModel 拍平序列化成 Json 串,那麼 A 只需要拼裝一個符合 B 頁面 scheme 的跳轉協議就可以了。 wsc://home/bbb?message={ “name”:”John”, “age”:31, “city”:”New York” }

在資訊清單檔中,配置data屬性,設定其host、path、scheme等

<activity android:name=".ui.BbbActivity"  <intent-filter>    <category android:name="android.intent.category.DEFAULT" />    <action android:name="android.intent.action.VIEW" />    <data      android:host="bbb"      android:path="/home"      android:scheme="wsc" />  </intent-filter></activity>

跳轉時:

final Uri uri = new Uri.Builder().authority("wsc").path("home/bbb").appendQueryParameter("message", new Gson().toJson(messageModel)).build();final Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(uri);startActivity(intent);

以上的方法,都不是我們想要的,接下來開始介紹我們的Router方案。

三、為什麼要用Router

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

四、實現思路

思路是這樣的:

使用註解,為每個目標Activity標註別名。在應用啟動時,對所有類進行掃名,將註解過的Activity存於路由表中。

跳轉時,在路由表中通過別名擷取目標Activity的class對象,使用Intent實現跳轉。

五、代碼實現

5.1 自訂註解

/** * Description: 路由跳轉介面 註解 * Created by jia on 2018/1/10. * 人之所以能,是相信能 */@Target(ElementType.TYPE) //註解作用於類型(類,介面,註解,枚舉)@Retention(RetentionPolicy.RUNTIME) //運行時保留,運行中可以處理@Documented // 產生javadoc檔案public @interface Action {  String DEFAULT = "js";  String value() default DEFAULT;}

關於自訂註解的詳細介紹,請閱讀我的文章java進階之自訂註解。這裡不再多說。

5.2 註解Activity

@Action("MainActivity")public class MainActivity extends BaseActivity implements TabLayout.OnTabSelectedListener {  ...}

在建立Activity時,用剛剛自訂的註解進行註解,為其注釋別名。

5.3 啟動時掃描

private void getAllActivities(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") && entryName.contains("Activity")) {        //通過反射獲得Activity類        Class entryClass = Class.forName(entryName);        if(entryClass.isAnnotationPresent(Action.class)) {          Action action = (Action)entryClass.getAnnotation(Action.class);          this.map.put(action.value(), entryClass);        }      }    }  } catch (Exception e) {    e.printStackTrace();  }}

在應用啟動時,Application中對包下的所有類進行掃描,先找到名字中到activity的(定義到activity包下),並將帶有註解標註的Activity,存入map中。

5.4 跳轉

/** * 頁面跳轉 * @param activity * @param alias */public void jumpActivity(Activity activity, String alias) throws ClassNotFoundException{  if(map.containsKey(alias)) {    Intent intent = new Intent(activity, map.get(alias));    activity.startActivity(intent);  } else {    throw new ClassNotFoundException();  }}

跳轉的時候傳入目標Activity的別名即可(這裡的別名就是註解的別名)。

總結

通過這種方式,解決了跳轉Activity所產生的的模組依賴問題,相較於原生方案,拓展性更強。但這種方案只是階段性的,還存在一些問題。首先,載入過程中,頻繁使用到反射,會產生效能問題。其次,對於每個Activity的別名,需要進行統一維護,增加了協作成本。還有待最佳化。

當然,市面上有很多流行的Router方案(如阿里的ARouter),這裡只是介紹了一個思路,有好的建議歡迎交流,一起進步。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援幫客之家。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.