Intent詳解(二)----Intent過濾器

_喂人民服霧_發表於2018-01-22

上次部落格中,介紹了Intent的啟動Actiity的過程,這次來開始研究Intent過濾器。

開始Intent過濾器之前,首先可以看下過濾器的三個標籤,具體參看下表。

標籤

屬性

說明

<action>

android:name

指定元件所能響應的動作,用字串表示,通常由Java類名和包的完全限定名構成

<category>

android:name

指定以何種方式去服務Intent請求的動作

 

 

<data>

android:host

指定一個有效的主機名

android:mimetype

指定元件能處理的資料型別

android:path

有效的URI路徑名

android:port

主機的有效埠號

android:scheme

所需要的特定協議

Category可以由系統提供也可以自定義,這裡附上一張系統提供的Category標籤表:

說明

ALTERNATIVE

Intent資料預設動作的一個可替換的執行方法

SELECTED_ALTERNATIVE

和ALTERNATIVE類似,但替換的執行方法不是指定的,而是被解析出來的

BROWSABLE

宣告Activity可以由瀏覽器啟動

DEFAULT

為Intent過濾器中定義的資料提供預設動作

HOME

裝置啟動後顯示的第一個Activity

LAUNCHER

決定程式是否顯示下程式列表中(一般為桌面)

接下來將分別介紹幾個常用Category的用途,首先是HOME,HOME的第一個作用是裝置開機時會給我們提供選擇進入哪個頁面,系統會列出所有的可供選擇的Activity;HOME的另一個作用是在應用中當我們點選home鍵之後,同樣的會彈出一個選擇頁面,結果如下圖兩張圖,左邊是開機時的,右邊是點選home鍵圖。

              

DEFAULT:如果一個Activity需要隱式啟動,那麼必須給它加上一個DEFAULT標籤,但是不僅僅只限於一個DEFAULT,還可以新增其他的Category。


LAUNCHER和MAIN:

android.intent.category.LAUNCHER決定應用程式是否顯示在程式列表裡。android.intent.action.MAIN決定應用程式中最先啟動的Activity。

 

下面我們來測試幾種情形:

第一種,有MAIN無LAUNCHER:

結果:直接執行app提示無預設Activity,執行單獨的Activity可以執行,但是著桌面沒有圖示。


第二種,有LAUNCHER無MAIN:

結果:同第一種情況一樣

 

第三種,有多個Activity同時有MAIN和LANUCHER

AndroidMainfest.xml程式碼示例:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <activity android:name=".MainActivity"
        android:label="MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <activity android:name=".SecondActivity"
        android:label="SecondActivity">
        <intent-filter tools:ignore="AppLinkUrlError">
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

 結果:桌面有兩個程式的圖示。


測試時需要注意,在兩個Activity中要分別設定label(應用程式的名稱),否則只會生成一個圖示。另外,在兩個Activity都沒有新增DEFAULT或者都新增了DEFAULT的前提下,兩個Activity在AndroidMainfest.xm中先後順序決定了程式首先啟動的是哪一個Activity。

 

現在再來解釋下DEFAULT對啟動順序的影響,如果兩個Activity中有一個新增了一個DEFAULT(前提是兩個Activity都新增了MAIN和LAUNCHER),那麼無論哪個Activity在前,都會先執行新增了DEFAULT的那個Activity,假如兩者都新增DEFAULT,那麼哪個首先執行取決於順序。不信的朋友可以自己試試。

 

Android系統的Intent的解析規則如下:

1. 一個意圖Intent至多隻會包含一個action和多個category,而一個intent filter 卻可以包含多個action和多個category。在intent與Intentfilter匹配時,要求在intent中出現的action和所有category必須全部包含在intent filter中。

 

2. Intent的資料data中Uri的每個子部需要與Intent filter<data>標籤中的屬性進行匹配,如果<data>標籤指定了協議,主機名,路徑,埠等,則需要完全匹配,任何不匹配的intent都將會被過濾掉。

 

3. 如果intent filter匹配的結果多於一個,則使用者來進行選擇。

 

4. 在 Intent中,最多指定一個“action”,而在intent filter中則可以指定多個action,只要intent filter中的action包含intent中的action,該intent就可以通過,未指定action的intent可以滿足intent filter指定的任意的action。

5. 一個activity可以包含多個intent-filter,對於包含多個intent-filter的activity,只要其中一個intent-filter被intent匹配則這個activity就可以被啟動。

 

解析規則這麼多,總的來說就一句話,intent通過程式碼設定的條件,無論是action還是category,只要是intent-filter的子集,那麼就可以匹配,如果有data的話,需要intent通過程式碼設定的data和intent-filter中data的內容完全一致(協議,主機名,路徑,埠等)才可以匹配。

相關文章