Activity學(xué)習(xí)(三):Intent 和 intent-filter匹配規(guī)則

Intent是一個(gè)消息傳遞對(duì)象,可以使用它向其他組件做一些請求操作挠羔。

盡管 Intent 可以通過多種方式促進(jìn)組件之間的通信许昨,但其基本用例主要包括以下三個(gè):

  • 啟動(dòng) Activity
  • 啟動(dòng)Service
  • 傳遞廣播

Intent 分為兩種:

  • 顯示Intent:知道明確的類名。按照類名來做相應(yīng)的操作褥赊。
  • 隱式Intent:不知道明確的類糕档。但是知道一些Action等,通過意圖過濾器匹配符合的組件。

顯示Intent

顯示的Intent 比較簡單速那。直接通過類名做相應(yīng)操作即可俐银,顯式 Intent 啟動(dòng) Activity 或服務(wù)時(shí),系統(tǒng)將立即啟動(dòng)對(duì)象中指定的應(yīng)用組件:

// 啟動(dòng)Activity
startActivity(new Intent(this, OtherActivity.class));

// 綁定Service
Intent intent = new Intent(this, BookService.class);
bindService(intent, conn, Context.BIND_AUTO_CREATE);

...

什么樣的Intent屬于顯示的Intent呢端仰?
Intent有個(gè)很重要的屬性: 組件名稱
區(qū)分Intent是顯示還是隱式的捶惜,就是你是否傳遞了** 組件名稱 **。

  • 對(duì)應(yīng)在 **Manifest ** 中就是 ** android:name=".act.MainActivity" **荔烧。
  • 對(duì)應(yīng)在Java中就是** ComponentName** 這個(gè)類吱七。

如果打開 **new Intent (Context, Activity.class) **的源碼:

public Intent(Context packageContext, Class<?> cls) {
    mComponent = new ComponentName(packageContext, cls);
}

代碼就一行,就是根據(jù)傳遞的ContextClass生成** ComponentName** 鹤竭。
因此踊餐,只要指定了** ComponentName** 對(duì)象,就屬于顯示啟動(dòng)臀稚。
所以以下代碼也是屬于顯示啟動(dòng):

Intent intent  = new Intent();
// com.demo  是應(yīng)用包名吝岭,在Manifest的package中查看
// com.demo.MainActivity 是要啟動(dòng)的組件的類名
intent.setComponent(new ComponentName("com.demo","com.demo.MainActivity"));
startActivity(intent);

注意1: *如果Activity不是入口Activity或者是一個(gè)Service組件,想要被其他應(yīng)用訪問吧寺,需要加上屬性 android:exported="true" *

注意2: *Service盡量使用顯示啟動(dòng)窜管。為了確保應(yīng)用的安全性,從 Android 5.0(API 級(jí)別 21)開始稚机,如果使用隱式 Intent 調(diào)用 bindService()幕帆,系統(tǒng)會(huì)引發(fā)異常。 *

隱式Intent

如果沒有指定 ComponentName 對(duì)象的Intent就屬于隱式意圖赖条。
隱式的Intent 就比較復(fù)雜了蜓肆,需要了解 Intent-Filter 的匹配規(guī)則。

intent-filter 中包含一下幾個(gè)內(nèi)容:

  • <action> 操作
  • <data> 數(shù)據(jù)
  • <category> 類別

使用隱式 Intent 時(shí)谋币,系統(tǒng)通過將 Intent 中的action仗扬、data、category 與 intent-filter 的內(nèi)容進(jìn)行匹配蕾额,只有action早芭、data、category這三部分都匹配成功诅蝶,這個(gè)intent-filter才算匹配成功退个。
這時(shí)有三種情況:

  • 如果 Intent 與 intent-filter匹配,則系統(tǒng)將啟動(dòng)該組件调炬,并向其傳遞 Intent對(duì)象语盈。
  • 如果多個(gè) Intent 過濾器匹配的話,則系統(tǒng)會(huì)顯示一個(gè)對(duì)話框缰泡,讓用戶選取相應(yīng)的應(yīng)用刀荒。
  • ** 如果匹配不成功,則調(diào)用將會(huì)失敗,且應(yīng)用會(huì)崩潰缠借。**

為了程序的健壯干毅,需要使用Intent 對(duì)象的 **resolveActivity() ** 做一個(gè)檢測。如果結(jié)果為非空泼返,則至少有一個(gè)應(yīng)用能夠處理該 Intent硝逢,且可以安全調(diào)用 startActivity()。 如果結(jié)果為空绅喉,則不應(yīng)使用該 Intent渠鸽,否則會(huì)引發(fā)異常。

匹配是要將代碼中的Intent 與 Manifest中配置的Intent-Filter進(jìn)行匹配

action匹配規(guī)則

Intent可以設(shè)置多個(gè)Action柴罐,** intent-filter **也可以設(shè)置多個(gè)Action徽缚。
匹配規(guī)則:

  • Intent中必須至少有一個(gè)Action,并且Intent中的Action必須都要在** intent-filter **中存在

category匹配規(guī)則

category與Action規(guī)則類似丽蝎,但是有點(diǎn)不同:

  • 在intent中可以不配置category,但是只要你配置了膀藐,不管配置幾個(gè)屠阻,都必須在Intent-Filter中找到相同項(xiàng)。

注意:
startActivity 或者 startActivityForResult 兩個(gè)方法中额各,系統(tǒng)會(huì)默認(rèn)為** Intent 加上一個(gè) android.intent.category.DEFAULT 屬性国觉。所以為了我們定義的組件可以隱式啟動(dòng),我們都必須在 intent-filter 中配置上這個(gè)虾啦,否則 category **無法匹配成功麻诀。

data匹配規(guī)則

data的匹配規(guī)則和前面也是類似的,只是data結(jié)構(gòu)稍微復(fù)雜一些傲醉。

  • 只要在Intent-Filter中存在data蝇闭,那么Intent中必須Intent-Filter中的一個(gè)data,才能成功硬毕。

data由一個(gè) URI 和 一個(gè) mimeType組成 呻引。
在data標(biāo)簽中可以只有URI 或者mimeType ,也可以兩者同時(shí)存在吐咳。

data的兩個(gè)屬性介紹:

  • mimeType 比較簡單逻悠,類似 text/plain、***image/**** 等韭脊。
  • URI 比較復(fù)雜童谒,結(jié)構(gòu)是:<scheme>://<host>:<port>/<path>

URI例子:content://com.example.project:200/folder/subfolder/etc

  • scheme: content
  • host: com.example.project
  • port: 200
  • path: folder/subfolder/etc

對(duì)應(yīng)到Intent-Filter中就是這幾個(gè)屬性:

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

這幾個(gè)屬性都是可選的,但是沪羔,如果沒有指定scheme饥伊,那么這個(gè)URI就是無效的。

URI的scheme 有兩個(gè)默認(rèn)值,contentfile撵渡。當(dāng)data標(biāo)簽中只有mimeType時(shí)融柬,我們可以使用contentfile去匹配。
同時(shí)下面兩種寫法是一樣的效果:

// 寫法1
<intent-filter>
    <data android:host="www.baidu.com" 
        android:port="8888"
        android:scheme="http" />
</intent-filter>
// 寫法2
<intent-filter>
    <data android:scheme="http"/>
    <data android:host="www.baidu.com"/>
    <data android:port="8888" />
</intent-filter>

同時(shí) Intent.setData() 和 Intent.setType() 趋距,會(huì)相互清空粒氧,所以要同時(shí)設(shè)置data和type需要使用 Intent.setDataAndType()方法。

總結(jié):
想要隱式Intent匹配成功节腐,action和data必須與Intent-Filter匹配外盯,category傳空也是ok的。
若Action有多個(gè)翼雀,匹配一個(gè)即可饱苟。
若想要傳category,傳的category狼渊,必須是相匹配的箱熬。

官方Intent的介紹

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市狈邑,隨后出現(xiàn)的幾起案子城须,更是在濱河造成了極大的恐慌,老刑警劉巖米苹,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糕伐,死亡現(xiàn)場離奇詭異,居然都是意外死亡蘸嘶,警方通過查閱死者的電腦和手機(jī)良瞧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來训唱,“玉大人褥蚯,你說我怎么就攤上這事】鲈觯” “怎么了遵岩?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巡通。 經(jīng)常有香客問我尘执,道長,這世上最難降的妖魔是什么宴凉? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任誊锭,我火速辦了婚禮,結(jié)果婚禮上弥锄,老公的妹妹穿的比我還像新娘丧靡。我一直安慰自己蟆沫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布温治。 她就那樣靜靜地躺著饭庞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪熬荆。 梳的紋絲不亂的頭發(fā)上舟山,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音卤恳,去河邊找鬼累盗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛突琳,可吹牛的內(nèi)容都是我干的若债。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拆融,長吁一口氣:“原來是場噩夢啊……” “哼蠢琳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起镜豹,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤傲须,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后逛艰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體躏碳,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搞旭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年散怖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片肄渗。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡镇眷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出翎嫡,到底是詐尸還是另有隱情欠动,我是刑警寧澤,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布惑申,位于F島的核電站具伍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏圈驼。R本人自食惡果不足惜人芽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望绩脆。 院中可真熱鬧萤厅,春花似錦橄抹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至名挥,卻和暖如春疟羹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背躺同。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國打工阁猜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蹋艺。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓剃袍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親捎谨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子民效,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Intent簡介Android中提供了Intent機(jī)制來協(xié)助應(yīng)用間的交互與通訊,Intent負(fù)責(zé)對(duì)應(yīng)用中一次操作的...
    Android_lml閱讀 957評(píng)論 1 7
  • Intent是一個(gè)消息傳遞對(duì)象涛救,我們一般用它來在組件間進(jìn)行通信畏邢。 一、Intent類型 Intent分為兩種類型:...
    sunnygarden閱讀 1,340評(píng)論 0 7
  • 注:本文完全拷貝自https://developer.android.com/guide/components/i...
    RxCode閱讀 1,740評(píng)論 1 13
  • 古時(shí)候人們過年检吆,往長處說舒萎,“過了臘八就是年,不到元宵不算完”蹭沛; 往中處說臂寝,“臘月二十三,老灶爺上天摊灭。大年三十回咆贬,破...
    耘心學(xué)堂閱讀 440評(píng)論 0 0
  • 人人都知道中國有八大菜系,廣州的面細(xì)細(xì)品味帚呼,大抵也可分四大品種: 歐成記銀絲面掏缎,竹園竹升面,婆婆寬面煤杀,堅(jiān)記伊府面眷蜈。...
    七辻屋賣饅頭的閱讀 1,258評(píng)論 2 0