Intent以及IntentFilter詳解

image.png

一、Intent與組件的關系
我們知道安卓有四大組件,其中的三種,Activity,Service,BroadCast都可以通過Intent進行數(shù)據(jù)傳遞。
(1)啟動Activity,通過Intent傳入startActivity方法來啟動一個Activity的實例,同時,Intent也可以攜帶數(shù)據(jù),傳遞給新的Activity。
(2)通過 Context.startService() 啟動一個服務,或者通過Context.bindService() 和后臺服務交互;
(3)通過廣播方法(比如 Context.sendBroadcast(),Context.sendOrderedBroadcast(),
Context.sendStickyBroadcast()) 發(fā)給broadcast receivers。
我們都知道,啟動Activity有兩種方式,顯示啟動和隱式啟動;隱式啟動需要Intent能夠匹配目標及組件的IntentFilter設置的過濾條件,如果不匹配,則無法啟動對應的Activity。IntentFilter主要有三部分組成,action、category、data,下面是一個過濾條件的示例:

<activity android:name=".view.SecondActivity">
            <intent-filter>
                <action android:name="com.kevenzheng.view.c"/>
                <action android:name="com.kevenzheng.view.d"/>
                <category android:name="com.kevenzheng.category.c"/>
                <category android:name="com.kevenzheng.category.d"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <data android:mimeType="text/plain"/>
            </intent-filter>
 </activity>

為了匹配過濾規(guī)則,必須同時匹配action類別、category類別、data類別才算完全匹配,只有完全匹配,才能成功啟動目標Activity。一個Activity可以有多個IntentFilter,一個Intent只要能夠匹配一組IntentFilter即可啟動對應的Activity。
1.action的匹配規(guī)則
action是一個字符串,系統(tǒng)預定義了一些action,我們也可以在應用中自定義自己的action。action的匹配規(guī)則是intent中的action必須和過濾規(guī)則中的action相同,也就是action的字符串值完全相同。一個過濾條件中可以有多個action,但是只需要與其中一個進行匹配則可。另外,action中的字符串區(qū)分大小寫,大小寫不同,則無法匹配成功。

2.category的匹配規(guī)則
category是一個字符串,系統(tǒng)預定義了一些category,但是我們也可以在自己的應用中自定義自己的category。category的匹配規(guī)則和action不同,它要求如果Intent中包含category,那么所有的category都必須和過濾規(guī)則中的其中一個category相同。如果Intent中沒有category也是可以匹配成功的,因為系統(tǒng)在調(diào)用startActivity或者startActivityForResult的時候,會默認為Intent加入到“android.intent.category.DEFAULT”這個category,同時,我們?yōu)榱薃ctivity能夠接受隱式啟動,就必須在intentFilter中指定“android.intent.category.DEFAULT”這個category。

3、data的匹配規(guī)則
data的匹配規(guī)則和action類似,如果過濾規(guī)則中定義了data,那么Intent中也必須定義可匹配的data。
data的語法如下所示:

  <data
                    android:host="string"
                    android:scheme="string"
                    android:port="string"
                    android:path="string"
                    android:pathPattern="string"
                    android:pathPrefix="string"
                    android:mimeType="string"
                />

data有兩部分組成,一部分是mimeType,另一部分是URI。mimeType是媒體類型,比如image/jpeg、audio/mpeg4-generic和video/等,表示圖片,文本,視頻等不同的格式。而URI包含的數(shù)據(jù)就多了,<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>],舉個百度的例子:
http://www.baidu.com:8080/search/info
Scheme:URI的模式,比如http、file、content等,如果URI中沒有指定Scheme,那么這個URI是無效的。
Host:URI的主機名,比如www.baidu.com,如果host未定義,那么這個URI也是無效的。
Port:URI中的端口號,比如8080,僅當URI同時擁有scheme/host的時候,port才有意義。
Path、pathPattern、pathPrefix:這三個參數(shù)表示的是路徑信息,path表示完整的路徑信息;pathPattern也表示完整的路徑信息,不過它里面可以包含通配符" * "," * "代表0個或多個任意字符,需要注意的是,由于正則表達式的規(guī)范,如果想表達真實的字符串,那么 " * "要寫成" \
"," \ "要寫成" \\ ";pathPrefix表示路徑的前綴信息。

intent.setDataAndType(Uri.parse("file://abc"),"text/plain");

另外,如果要為Intent指定完整的data,必須要調(diào)用setDataAndType方法,因為單獨調(diào)用setData或者setType,會彼此清除對方的值,這個可以通過查看源碼獲得。

當我們通過隱式方式啟動一個Activity的時候,可以做下判斷,查看是否有Activity能夠匹配我們的隱式Intent,否則如果不存在此Activity,則會報錯。判斷的方法有兩種:采用PackageManager的resolveActivity方法或者Intent的resolveActivity方法,如果找不到對應的Activity,則會返回null,我們通過判斷,則會避免類似的錯誤。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容