国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

Router解決跨模塊下的頁(yè)面跳轉(zhuǎn)示例

2019-11-19 14:32:43
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

一、前言

開(kāi)始模塊化開(kāi)發(fā)項(xiàng)目之后,一個(gè)很重要的問(wèn)題就是頁(yè)面見(jiàn)的跳轉(zhuǎn)問(wèn)題。

關(guān)于模塊化發(fā)開(kāi),可詳見(jiàn)我的另一片文章 Android模塊化開(kāi)發(fā)探索 。

正是由于將項(xiàng)目模塊化拆分,各模塊之間沒(méi)有任何依賴(lài)關(guān)系,也互相不可見(jiàn),那么從A模塊的a界面跳轉(zhuǎn)到B模塊的b界面該怎么辦呢?

二、跨模塊跳轉(zhuǎn)的方法

這里我們會(huì)先介紹這幾種常見(jiàn)的跳轉(zhuǎn)方法:

  1. 顯示跳轉(zhuǎn)
  2. 隱示跳轉(zhuǎn)
  3. Scheme協(xié)議跳轉(zhuǎn)
  4. Router路由表方案

2.1 顯示跳轉(zhuǎn)

顯示跳轉(zhuǎn)即我們最最常用的跳轉(zhuǎn)方法:使用Intent,傳入當(dāng)前Activity上下文,和目標(biāo)Activity的class對(duì)象即可,如下:

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

顯然,這種方法只能是目標(biāo)Activity可見(jiàn)(Activity在同一個(gè)Module下)的時(shí)候才可以這樣調(diào)用。不適合跨模塊間的跳轉(zhuǎn)。

2.2 隱示跳轉(zhuǎn)

我們這里說(shuō)的隱示跳轉(zhuǎn),intent不設(shè)置class,而是設(shè)置Action或者Category。

例如:

在清單文件中

<!--網(wǎng)頁(yè)展示界面--><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>

跳轉(zhuǎn)時(shí):

//創(chuàng)建一個(gè)隱式的 Intent 對(duì)象:Action 動(dòng)作 Intent intent = new Intent(); //設(shè)置 Intent 的動(dòng)作為清單中指定的action intent.setAction("com.whaty.base.BaseWebViewActivity"); startActivity(intent);

2.3 scheme跳轉(zhuǎn)

如果我們?yōu)?B 頁(yè)面定義一個(gè) URI - wsc://home/bbb,然后把共享的 messageModel 拍平序列化成 Json 串,那么 A 只需要拼裝一個(gè)符合 B 頁(yè)面 scheme 的跳轉(zhuǎn)協(xié)議就可以了。 wsc://home/bbb?message={ “name”:”John”, “age”:31, “city”:”New York” }

在清單文件中,配置data屬性,設(shè)置其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>

跳轉(zhuǎn)時(shí):

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);

以上的方法,都不是我們想要的,接下來(lái)開(kāi)始介紹我們的Router方案。

三、為什么要用Router

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

四、實(shí)現(xiàn)思路

思路是這樣的:

使用注解,為每個(gè)目標(biāo)Activity標(biāo)注別名。在應(yīng)用啟動(dòng)時(shí),對(duì)所有類(lèi)進(jìn)行掃名,將注解過(guò)的Activity存于路由表中。

跳轉(zhuǎn)時(shí),在路由表中通過(guò)別名獲取目標(biāo)Activity的class對(duì)象,使用Intent實(shí)現(xiàn)跳轉(zhuǎn)。

五、代碼實(shí)現(xiàn)

5.1 自定義注解

/** * Description: 路由跳轉(zhuǎn)界面 注解 * Created by jia on 2018/1/10. * 人之所以能,是相信能 */@Target(ElementType.TYPE) //注解作用于類(lèi)型(類(lèi),接口,注解,枚舉)@Retention(RetentionPolicy.RUNTIME) //運(yùn)行時(shí)保留,運(yùn)行中可以處理@Documented // 生成javadoc文件public @interface Action {  String DEFAULT = "js";  String value() default DEFAULT;}

關(guān)于自定義注解的詳細(xì)介紹,請(qǐng)閱讀我的文章java進(jìn)階之自定義注解。這里不再多說(shuō)。

5.2 注解Activity

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

在創(chuàng)建Activity時(shí),用剛剛自定義的注解進(jìn)行注解,為其注釋別名。

5.3 啟動(dòng)時(shí)掃描

private void getAllActivities(Context ctx){  try {    //通過(guò)資源路徑獲得DexFile    DexFile e = new DexFile(ctx.getPackageResourcePath());    Enumeration entries = e.entries();    //遍歷所有元素    while(entries.hasMoreElements()) {      String entryName = (String)entries.nextElement();      //匹配Activity包名與類(lèi)名      if(entryName.contains("activity") && entryName.contains("Activity")) {        //通過(guò)反射獲得Activity類(lèi)        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();  }}

在應(yīng)用啟動(dòng)時(shí),Application中對(duì)包下的所有類(lèi)進(jìn)行掃描,先找到名字中到activity的(定義到activity包下),并將帶有注解標(biāo)注的Activity,存入map中。

5.4 跳轉(zhuǎn)

/** * 頁(yè)面跳轉(zhuǎn) * @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();  }}

跳轉(zhuǎn)的時(shí)候傳入目標(biāo)Activity的別名即可(這里的別名就是注解的別名)。

總結(jié)

通過(guò)這種方式,解決了跳轉(zhuǎn)Activity所產(chǎn)生的的模塊依賴(lài)問(wèn)題,相較于原生方案,拓展性更強(qiáng)。但這種方案只是階段性的,還存在一些問(wèn)題。首先,加載過(guò)程中,頻繁使用到反射,會(huì)產(chǎn)生性能問(wèn)題。其次,對(duì)于每個(gè)Activity的別名,需要進(jìn)行統(tǒng)一維護(hù),增加了協(xié)作成本。還有待優(yōu)化。

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 安仁县| 肇庆市| 涟水县| 荥经县| 行唐县| 繁昌县| 六盘水市| 三台县| 宾川县| 卢湾区| 法库县| 介休市| 东源县| 威信县| 根河市| 农安县| 阿勒泰市| 三穗县| 乡宁县| 桂阳县| 信阳市| 尉犁县| 新民市| 舞阳县| 博爱县| 大宁县| 宝丰县| 上饶县| 宝兴县| 河西区| 宾阳县| 罗平县| 芜湖县| 庐江县| 沧源| 东乡族自治县| 宜黄县| 额济纳旗| 许昌县| 禄劝| 抚宁县|