淺談關(guān)于Android路由的實(shí)現(xiàn)

先說(shuō)一下背景,目前有需求從外部包括其他應(yīng)用和WEB跳轉(zhuǎn)到我們自己的APP,就這么個(gè)簡(jiǎn)單的需求……

創(chuàng)新互聯(lián)專(zhuān)業(yè)為企業(yè)提供成武網(wǎng)站建設(shè)、成武做網(wǎng)站、成武網(wǎng)站設(shè)計(jì)、成武網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、成武企業(yè)網(wǎng)站模板建站服務(wù),10余年成武做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

要實(shí)現(xiàn)這種外部跳轉(zhuǎn)的功能,我們可以理解為打算跳轉(zhuǎn)的一方有多少方式通知到APP進(jìn)行相對(duì)的響應(yīng)行為。所以,如果是應(yīng)用之間的跳轉(zhuǎn),則有多種,你可以直接通過(guò)包名和具體的類(lèi)名去打開(kāi)已經(jīng)exported=true的Activity,又或者直接通過(guò)Android的廣播通知進(jìn)行相關(guān)的APP,又或者通過(guò)自定義的URL去打開(kāi)應(yīng)用。但是如果涉及到Web打開(kāi)外部應(yīng)用的話,目前只有一種辦法,那就是自定義應(yīng)用的URL進(jìn)行攔截,系統(tǒng)會(huì)自動(dòng)調(diào)起相應(yīng)的組件響應(yīng)這個(gè)URL。

但是,要做這種需求,很少會(huì)僅僅是完成對(duì)外部的支持而已,通常也要進(jìn)行一定的內(nèi)部邏輯跳轉(zhuǎn)映射。所以要做這種需求通常分為兩個(gè)種,一種是對(duì)內(nèi)的(應(yīng)用內(nèi)部自己的跳轉(zhuǎn)邏輯),一種對(duì)外的(其他應(yīng)用以及Web跳轉(zhuǎn)邏輯)。

我們先說(shuō)一下對(duì)外的情形,由于考慮到統(tǒng)一性,我們目前只有URL這種手段可以使用了。下面我們一一來(lái)說(shuō)

1、對(duì)外跳轉(zhuǎn)說(shuō)明

1.1、關(guān)于URL的說(shuō)明。

首先,我們得了解一下URL,這里直接引用 https://en.wikipedia.org/wiki/URL 的說(shuō)明。為了方便說(shuō)明,我稍稍修改一下,大概的格式如下:

scheme:[//host[:port]][/path][?query][#fragment]

首先,scheme是必須的,其他的都是不必須的,但是對(duì)于跳轉(zhuǎn)來(lái)說(shuō),顯然不可能,因?yàn)槟阋獜倪@個(gè)url中取出跳轉(zhuǎn)相關(guān)的信息。所以,通常一定要要有host和query。我們經(jīng)??吹揭恍╅_(kāi)源的路由實(shí)現(xiàn),都會(huì)支持所謂的restful風(fēng)格的url,比如:wytings://app/{city}/{id} ,但我個(gè)人認(rèn)為是沒(méi)有必要的。主要是因?yàn)檫@種外部跳轉(zhuǎn)的行為,通常量比較少,其次應(yīng)該盡量統(tǒng)一而且方便,而不是為了追求各種技術(shù)炫酷…我刻意看了微信的scheme就甚合我意~都是類(lèi)似于這種格式:weixin://qrscan?a=1&b=2

我們進(jìn)行一下歸納,就可以進(jìn)行應(yīng)用的URL定義了,首先scheme是必須項(xiàng),看個(gè)人和公司要求,比如接下來(lái)要舉的例子,我定義的scheme為wytings,然后支持的模塊都集中于host字段,具體參數(shù)則全部通過(guò)query補(bǔ)充。比如:wytings://user?uin=10000 打開(kāi)個(gè)人頁(yè)面,wytings://stockDetail?marketcode=hk&stockcode=00376 打開(kāi)股票詳情頁(yè)面等等。

要是對(duì)外部的支持,通常我們不會(huì)對(duì)每一個(gè)要支持的Activity都進(jìn)行相應(yīng)的intent-filter限制,而是定義一個(gè)公共的Activity進(jìn)行所有外部請(qǐng)求的攔截形如:

<activity
      android:name=".activity.SchemeFilterActivity"
      android:exported="true"
      android:theme="@android:style/Theme.NoDisplay">

      <intent-filter>

        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data android:scheme="wytings" />

      </intent-filter>

      <intent-filter
        android:autoVerify="true"
        tools:targetApi="m">
        <action android:name="android.intent.action.VIEW" />

        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />

        <data
          android:host="native.app.wytings.com"
          android:scheme="http" />
        <data
          android:host="native.app.wytings.com"
          android:scheme="https" />
      </intent-filter>
    </activity>

我們對(duì)這個(gè)Activity的定義進(jìn)行一下說(shuō)明:

a、android:exported這個(gè)屬性其默認(rèn)是false就是對(duì)外不開(kāi)放,我們必須要設(shè)置為true,因?yàn)槲覀円屚獠磕軌驅(qū)ζ溥M(jìn)行訪問(wèn)。

b、android:theme="@android:style/Theme.NoDisplay" 由于是作為攔截的Activity,所以,沒(méi)必要展示,但是這個(gè)NoDisplay的theme要求必須在onResume前finish掉Activity,否則要報(bào)錯(cuò)。

c、第一個(gè)intent-filter自定義scheme為wytings,也就是攔截該類(lèi)URL。

d、第二個(gè)scheme為http,但是加了特別的host=nativ.app.wytings.com,進(jìn)一步詳細(xì)攔截url為:http://nativ.app.wytings.com 的url。為什么要攔截這種url,通常情況下不用,但是特殊情況下,有時(shí)候自定義的scheme可能失效,所以而外再加層保障,當(dāng)然,也要與調(diào)用方預(yù)定好url格式,比如:http://nativ.app.wytings.com/stockDetail?marketCode=hk&stockCode=00376,由于host已經(jīng)被定義為別的,所以我們把具體模塊定義在path里面,參數(shù)依然保留在query中。

再來(lái)看看SchemeFilterActivity的實(shí)現(xiàn)情況:

/**
 * Created by rex on 06/10/2017.
 *
 * @author wytings@gmail.com
 */

public class SchemeFilterActivity extends Activity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Uri uri = getIntent().getData();
    Log.i("wytings", "uri = " + uri);

    String scheme = uri.getScheme();
    if ("http".equals(scheme) || "https".equals(scheme)) {
      String routeModule = uri.getLastPathSegment();
      if (!TextUtils.isEmpty(routeModule)) {
        RouteManager.getInstance().build(routeModule + "?" + uri.getQuery()).go(this);
      }
    } else {
      RouteManager.getInstance().build(uri.toString()).go(this);
    }

    finish();
  }

}

大體就是攔截,然后通過(guò)內(nèi)部的RouteManager進(jìn)行解析處理跳轉(zhuǎn)。RouteManager怎么處理和實(shí)現(xiàn)就太細(xì)節(jié)了,總的來(lái)說(shuō),這個(gè)Manager的職責(zé)就是把URL翻譯成具體的Intent,然后啟動(dòng)相應(yīng)的Activity。有興趣的同學(xué)可以自己去看看本篇文章的所有源碼:https://github.com/wytings/AndroidRoute

2、對(duì)內(nèi)跳轉(zhuǎn)說(shuō)明

由于是應(yīng)用內(nèi)的實(shí)現(xiàn),所以基本上,你想怎么實(shí)現(xiàn)就怎么實(shí)現(xiàn)。但是,無(wú)論多么變幻莫測(cè),都繞不開(kāi)一個(gè)核心那就是建立路由映射關(guān)系,打開(kāi)相關(guān)頁(yè)面,取出請(qǐng)求參數(shù)這三大步驟。我們逐個(gè)來(lái)分析一下。

2.1、建立路由映射關(guān)系

這個(gè)是為了能夠知道特定的url到底應(yīng)該展示哪個(gè)頁(yè)面。通常建立一個(gè)Map,然后查找。

2.3、打開(kāi)相關(guān)頁(yè)面

在Android中,打開(kāi)一個(gè)頁(yè)面總是有自己的一套邏輯,系統(tǒng)那一套則是通過(guò)Intent去啟動(dòng)相應(yīng)的組件展示。

2.4、取出參數(shù)

這個(gè)步驟,還是基于系統(tǒng)的Intent方式,要通過(guò)intent.getXXXExtra來(lái)取出相關(guān)參數(shù)。

這么一看好像,也沒(méi)什么難度。也確實(shí)沒(méi)什么難度,就單純實(shí)現(xiàn)功能來(lái)說(shuō)。那難點(diǎn)在哪呢?難點(diǎn)在于你決定使用注解去做這件事……為什么要用注解?因?yàn)闉榱四囊欢↑c(diǎn)潔癖,解藕的潔癖。結(jié)果掉進(jìn)坑里了…

用注解理論上,也還好,遍歷反射嘛,而且我個(gè)人測(cè)試了一下,就目前的機(jī)器真的感受不出來(lái)。當(dāng)然再怎么樣,也沒(méi)在編譯時(shí)直接生成相關(guān)代碼來(lái)得快倒是真的……

于是乎,進(jìn)入第三個(gè)大難題,那就是進(jìn)行編譯時(shí)生成代碼,類(lèi)似于ButterKnife一樣,在編譯期就生成相關(guān)代碼,而不是在運(yùn)行時(shí)通過(guò)反射來(lái)給變量賦值。

這里就涉及到一個(gè)東西,那就是Java 的 AbstractProcessor,這個(gè)類(lèi)是在編譯時(shí)生成代碼最關(guān)鍵的類(lèi)。要講解這個(gè)得再開(kāi)一篇《關(guān)于Java注解實(shí)現(xiàn)編譯時(shí)生成代碼》的文章了。同學(xué)們可以網(wǎng)上搜索一下基本知識(shí),然后再看這個(gè)項(xiàng)目中的代碼,我自己也看了很多關(guān)于注解的文章,但是很遺憾,我沒(méi)看到哪篇是值得捧的,同樣也沒(méi)看到那篇值得噴的……我現(xiàn)在也沒(méi)時(shí)間專(zhuān)門(mén)寫(xiě)篇關(guān)于注解的文章,但是可以給個(gè)方向,那就是先學(xué)會(huì)調(diào)試,AnnotatioProcessor的調(diào)試,跟普通java調(diào)試有點(diǎn)區(qū)別(自己google一下),然后就可以自己摸索了。另外,我審視了一下,我寫(xiě)的Annotation compiler還是蠻清晰的,你也可以試著看看。

最后,再說(shuō)一遍,項(xiàng)目地址:AndroidRoute

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

網(wǎng)頁(yè)題目:淺談關(guān)于Android路由的實(shí)現(xiàn)
網(wǎng)頁(yè)URL:http://muchs.cn/article6/gdihog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)、微信小程序、搜索引擎優(yōu)化、網(wǎng)站制作網(wǎng)站改版、用戶(hù)體驗(yàn)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站