溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Android路由框架Router分析詳解

發(fā)布時(shí)間:2020-08-24 09:30:34 來(lái)源:腳本之家 閱讀:258 作者:FullStack 欄目:移動(dòng)開(kāi)發(fā)

什么是路由?說(shuō)簡(jiǎn)單點(diǎn)就是映射頁(yè)面跳轉(zhuǎn)關(guān)系的,當(dāng)然它也包含跳轉(zhuǎn)相關(guān)的一切功能。

路由框架的意義

Android系統(tǒng)已經(jīng)給我們提供了api來(lái)做頁(yè)面跳轉(zhuǎn),比如startActivity,為什么還需要路由框架呢?我們來(lái)簡(jiǎn)單分析下路由框架存在的意義:

  • 在一些復(fù)雜的業(yè)務(wù)場(chǎng)景下(比如電商),靈活性比較強(qiáng),很多功能都是運(yùn)營(yíng)人員動(dòng)態(tài)配置的,比如下發(fā)一個(gè)活動(dòng)頁(yè)面,我們事先并不知道具體的目標(biāo)頁(yè)面,但如果事先做了約定,提前做好頁(yè)面映射,便可以自由配置。
  • 隨著業(yè)務(wù)量的增長(zhǎng),客戶端必然隨之膨脹,開(kāi)發(fā)人員的工作量越來(lái)越大,比如64K問(wèn)題,比如協(xié)作開(kāi)發(fā)問(wèn)題。App一般都會(huì)走向組件化、插件化的道路,而組件化、插件化的前提就是解耦,那么我們首先要做的就是解耦頁(yè)面之間的依賴關(guān)系。
  • 簡(jiǎn)化代碼。數(shù)行跳轉(zhuǎn)代碼精簡(jiǎn)成一行代碼。
  • 其他...

工作流程圖

Router的工作流程簡(jiǎn)要如下圖:

Android路由框架Router分析詳解

特性

Router有哪些特性或者有點(diǎn)呢?

  • 簡(jiǎn)單
  • 鏈?zhǔn)秸{(diào)用,api友好
  • 多路徑支持
  • 結(jié)果回調(diào),每次跳轉(zhuǎn)都會(huì)回調(diào)跳轉(zhuǎn)結(jié)果
  • 編譯期處理注解,沒(méi)有使用反射,不影響運(yùn)行時(shí)性能
  • 除了可以使用注解定義路由,還支持手動(dòng)分配路由
  • 自定義攔截器,可以對(duì)路由進(jìn)行攔截,比如登錄判斷和埋點(diǎn)處理
  • 自定義路由匹配規(guī)則,相比較其他路由框架,該項(xiàng)目并沒(méi)有寫死路由的匹配規(guī)則,除了內(nèi)置的幾個(gè)匹配器,用戶完全可以定義自己的規(guī)則
  • 支持隱式Intent跳轉(zhuǎn)
  • 支持多模塊使用,支持組件化開(kāi)發(fā)

集成

集成過(guò)程也可參考項(xiàng)目主頁(yè)README。

1、在項(xiàng)目級(jí)的build.gradle中加入依賴:

 buildscript {
   repositories {
     jcenter()
   }
   dependencies {
     classpath 'com.android.tools.build:gradle:2.2.x ↑'
     classpath 'com.chenenyu.router:gradle-plugin:latest.integration'
   }
 }

 // Optional. Specify the dependencies version, default to the latest version.
 ext {
   ...
   routerVersion = "x.y.z"
   compilerVersion = "x.y.z"
 }

其中ext中的配置是可選的,用來(lái)指定依賴的router和注解處理器的版本,默認(rèn)為最新的版本。

注意,Router需要使用2.2.0及以上版本的Android gradle plugin來(lái)處理注解處理器,截至寫作時(shí),最新版本為2.3.0-beta2。

2、在module級(jí)的build.gradle中使用plugin:

 apply plugin: 'com.android.application/library'
 apply plugin: 'com.chenenyu.router'

至此,集成工作就完成了,簡(jiǎn)單的兩步:添加依賴插件和應(yīng)用插件。

使用

1、Router需要初始化,用于初始化路由表,建議放到Application中做:

 public class App extends MultiDexApplication {
   @Override
   public void onCreate() {
     super.onCreate();
     // 初始化
     Router.initialize(this);
     // 開(kāi)啟log
     if (BuildConfig.DEBUG) {
       Router.openLog();
     }
   }
 }

2、添加注解

 // 單路徑注解
 @Route("test")
 public class TestActivity extends Activity {
 ...
 }

 // 多路徑注解,這幾個(gè)注解都能打開(kāi)該Activity
 @Route({"user", "example://user", "http://example.com/user"})
 public class UserActivity extends Activity {
 ...
 }

3、發(fā)起路由操作

 // 最簡(jiǎn)單的路由跳轉(zhuǎn),打開(kāi)TestActivity
 Router.build("test").go(context);

 // 其他部分api
 Router.build("user")
   .requestCode(int) // 調(diào)用startActivityForResult
   .extras(bundle) // 攜帶跳轉(zhuǎn)參數(shù)
   .addFlags(flag) // 添加標(biāo)記,比如intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
   .anim(enter, exit) // 添加跳轉(zhuǎn)動(dòng)畫
   .callback(calback) // 跳轉(zhuǎn)結(jié)果回調(diào)
   .go(context);

進(jìn)階

自定義路由表

Router除了可以使用注解來(lái)做映射,還支持在代碼中自定義:

// 動(dòng)態(tài)添加路由
Router.addRouteTable(new RouteTable() {
  @Override
  public void handleActivityTable(Map<String, Class<? extends Activity>> map) {
    map.put("dynamic", DynamicActivity.class);
  }
});

即路由表由兩部分組成,一部分是注解,另一部分是手動(dòng)添加的。

攔截器

Router支持?jǐn)r截器的配置,比如在跳轉(zhuǎn)前做登錄狀態(tài)的校驗(yàn),

Router.addRouteInterceptor(new RouteInterceptor() {
  @Override
  public boolean intercept(Context context, @NonNull Uri uri, @Nullable Bundle extras) {
    // operation.
    return false;
  }
});

intercept方法返回true即表示攔截該路由,false表示不攔截。攔截器可以添加多個(gè),依次調(diào)用,方便協(xié)作開(kāi)發(fā)。

自定義路由解析規(guī)則

該功能是Router的特色功能之一。由于每個(gè)產(chǎn)品的業(yè)務(wù)都不一樣,靈活的路由處理規(guī)則是十分必要的。用戶可以借鑒Router內(nèi)置的幾個(gè)匹配器(Matcher),來(lái)實(shí)現(xiàn)自己的規(guī)則。

內(nèi)置的Matcher

Router目前內(nèi)置了4個(gè)Matcher,已經(jīng)能適用絕大部分業(yè)務(wù)場(chǎng)景,優(yōu)先級(jí)從高到低分別是SimpleMatcher(0x1000)、SchemeMatcher(0x0100)、ImplicitMatcher(0x0010)、BrowserMatcher(0x0000),優(yōu)先級(jí)高的Matcher會(huì)優(yōu)先匹配。

自定義Matcher

自定義的Matcher需要繼承Matcher抽象類,指定該Matcher的優(yōu)先級(jí),并實(shí)現(xiàn)兩個(gè)抽象方法:

// 返回true表示當(dāng)前路由被該Matcher匹配,返回false則會(huì)繼續(xù)匹配其他Matcher
public abstract boolean match(Context context, Uri uri, @Nullable String route, RouteOptions routeOptions);

// match方法返回true后會(huì)調(diào)用該方法,用來(lái)生成一個(gè)Intent對(duì)象
public abstract Intent onMatched(Context context, Uri uri, @Nullable Class<? extends Activity> target);

然后調(diào)用Router.registerMatcher(new CustomMatcher(int priority));來(lái)注冊(cè)自定義的Matcher。

Matcher支持配置多個(gè),會(huì)依次進(jìn)行匹配。

其他

獲取Intent

Intent intent = Router.build(uri).getIntent(context);,即可獲取一個(gè)符合路由規(guī)則Intent對(duì)象,然后你可以使用這個(gè)intent來(lái)跳轉(zhuǎn),或者發(fā)一個(gè)通知。

顯示log

在調(diào)試過(guò)程中,可能需要打印Router相關(guān)的log,通過(guò)Router.openLog()即可打開(kāi),建議在debug環(huán)境下打開(kāi)。

總結(jié)

Router是一個(gè)十分小巧靈活的路由框架,代碼設(shè)計(jì)也很優(yōu)雅簡(jiǎn)潔,且完美支持組件化開(kāi)發(fā),目前仍在不斷地迭代中。

源碼地址為:Router_jb51.rar

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

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI