安卓 topic-意圖 Intent

意圖是安卓中重要核心組件之一。

Intent 是一個消息傳遞對象,您可以使用它從其他應(yīng)用組件請求操作。盡管 Intent 可以通過多種方式促進(jìn)組件之間的通信礁扮,但其基本用例主要包括以下三個:

  • 啟動 Activity
  • 啟動服務(wù)
  • 傳遞廣播

Intent 分為兩種類型:

  • 顯式 Intent:按名稱(完全限定類名)指定要啟動的組件。 通常瞬沦,您會在自己的應(yīng)用中使用顯式 Intent 來啟動組件太伊,這是因?yàn)槟酪獑拥?Activity 或服務(wù)的類名。例如逛钻,啟動新 Activity 以響應(yīng)用戶操作僚焦,或者啟動服務(wù)以在后臺下載文件。
  • 隱式 Intent :不會指定特定的組件曙痘,而是聲明要執(zhí)行的常規(guī)操作芳悲,從而允許其他應(yīng)用中的組件來處理它。 例如边坤,如需在地圖上向用戶顯示位置名扛,則可以使用隱式 Intent,請求另一具有此功能的應(yīng)用在地圖上顯示指定的位置茧痒。

[圖片上傳失敗...(image-976dbc-1640352429584)]
肮韧,并將其傳遞給 startActivity()[2]Android 系統(tǒng)搜索所有應(yīng)用中與 Intent 匹配的 Intent 過濾器。** 找到匹配項(xiàng)之后弄企,[3] 該系統(tǒng)通過調(diào)用匹配 Activity(Activity B)的 onCreate() 方法并將其傳遞給 Intent超燃,以此啟動匹配 Activity](http://upload-images.jianshu.io/upload_images/1662509-6496761370a9e66c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

注意:為了確保應(yīng)用的安全性,啟動 Service
時桩蓉,請始終使用顯式 Intent淋纲,且不要為服務(wù)聲明 Intent 過濾器劳闹。使用隱式 Intent 啟動服務(wù)存在安全隱患院究,因?yàn)槟鸁o法確定哪些服務(wù)將響應(yīng) Intent,且用戶無法看到哪些服務(wù)已啟動本涕。從 Android 5.0(API 級別 21)開始业汰,如果使用隱式 Intent 調(diào)用 [bindService()](http://developer.android.youdaxue.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)),系統(tǒng)會引發(fā)異常菩颖。

顯式 Intent 示例

顯式 Intent 是指用于啟動某個特定應(yīng)用組件(例如样漆,應(yīng)用中的某個特定 Activity 或服務(wù))的 Intent。 要創(chuàng)建顯式 Intent晦闰,請為 Intent 對象定義組件名稱 — Intent 的所有其他屬性均為可選屬性放祟。
例如,如果在應(yīng)用中構(gòu)建了一個名為 DownloadService呻右、旨在從網(wǎng)頁下載文件的服務(wù)跪妥,則可使用以下代碼啟動該服務(wù):

// Executed in an Activity, so 'this' is the Context
// The fileUrl is a string URL, such as "http://www.example.com/image.png"
Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);
隱式 Intent 示例

注意:用戶可能沒有任何應(yīng)用處理您發(fā)送到 startActivity() 的隱式 Intent。如果出現(xiàn)這種情況声滥,則調(diào)用將會失敗眉撵,且應(yīng)用會崩潰。要驗(yàn)證 Activity 是否會接收 Intent落塑,請對 Intent 對象調(diào)用 resolveActivity()纽疟。如果結(jié)果為非空,則至少有一個應(yīng)用能夠處理該 Intent憾赁,且可以安全調(diào)用startActivity()污朽。 如果結(jié)果為空,則不應(yīng)使用該 Intent龙考。如有可能蟆肆,您應(yīng)停用發(fā)出該 Intent 的功能。

// Create the text message with a string
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(sendIntent);
}
強(qiáng)制使用應(yīng)用選擇器

如果有多個應(yīng)用響應(yīng)隱式 Intent洲愤,則用戶可以選擇要使用的應(yīng)用颓芭,并將其設(shè)置為該操作的默認(rèn)選項(xiàng)。 如果用戶可能希望今后一直使用相同的應(yīng)用執(zhí)行某項(xiàng)操作(例如柬赐,打開網(wǎng)頁時亡问,用戶往往傾向于僅使用一種網(wǎng)絡(luò)瀏覽器),則這一點(diǎn)十分有用。
但是州藕,如果多個應(yīng)用可以響應(yīng) Intent束世,且用戶可能希望每次使用不同的應(yīng)用,則應(yīng)采用顯式方式顯示選擇器對話框床玻。 選擇器對話框每次都會要求用戶選擇用于操作的應(yīng)用(用戶無法為該操作選擇默認(rèn)應(yīng)用)毁涉。 例如,當(dāng)應(yīng)用使用ACTION_SEND 操作執(zhí)行“共享”時锈死,用戶根據(jù)目前的狀況可能需要使用另一不同的應(yīng)用贫堰,因此應(yīng)當(dāng)始終使用選擇器對話框,如圖 2 中所示待牵。要顯示選擇器其屏,請使用 [createChooser()](http://developer.android.youdaxue.com/reference/android/content/Intent.html#createChooser(android.content.Intent, java.lang.CharSequence)) 創(chuàng)建 Intent
,并將其傳遞給 startActivity()缨该。例如:

選擇器對話框偎行。
Intent sendIntent = new Intent(Intent.ACTION_SEND);
...

// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);

// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

使用待定 Intent

PendingIntent 對象是 Intent 對象的包裝器。PendingIntent 的主要目的是授權(quán)外部應(yīng)用使用包含的 Intent贰拿,就像是它從您應(yīng)用本身的進(jìn)程中執(zhí)行的一樣蛤袒。

待定 Intent 的主要用例包括:

  • 聲明用戶使用您的通知執(zhí)行操作時所要執(zhí)行的 Intent(Android 系統(tǒng)的 NotificationManager 執(zhí)行 Intent)。
  • 聲明用戶使用您的 應(yīng)用小部件執(zhí)行操作時要執(zhí)行的 Intent(主屏幕應(yīng)用執(zhí)行 Intent
    )膨更。
  • 聲明未來某一特定時間要執(zhí)行的 Intent(Android 系統(tǒng)的 AlarmManager 執(zhí)行 Intent)妙真。

由于每個 Intent 對象均設(shè)計為由特定類型的應(yīng)用組件(ActivityServiceBroadcastReceiver)進(jìn)行處理询一,因此還必須基于相同的考慮因素創(chuàng)建PendingIntent隐孽。使用待定 Intent 時,應(yīng)用不會使用調(diào)用(如 startActivity())執(zhí)行該 Intent健蕊。相反菱阵,通過調(diào)用相應(yīng)的創(chuàng)建器方法創(chuàng)建PendingIntent 時,您必須聲明所需的組件類型:

除非您的應(yīng)用正在從其他應(yīng)用中接收待定 Intent缩功,否則上述用于創(chuàng)建 PendingIntent 的方法可能是您所需的唯一 PendingIntent 方法晴及。

每種方法均會提取當(dāng)前的應(yīng)用 Context、您要包裝的 Intent 以及一個或多個指定應(yīng)如何使用該 Intent 的標(biāo)志(例如嫡锌,是否可以多次使用該 Intent)虑稼。

如需了解有關(guān)使用待定 Intent 的詳細(xì)信息,請參閱通知應(yīng)用小部件 API 指南等手冊中每個相應(yīng)用例的相關(guān)文檔势木。

Intent 解析

當(dāng)系統(tǒng)收到隱式 Intent 以啟動 Activity 時蛛倦,它根據(jù)以下三個方面將該 Intent 與 Intent 過濾器進(jìn)行比較,搜索該 Intent 的最佳 Activity:

  • Intent 操作
  • Intent 數(shù)據(jù)(URI 和數(shù)據(jù)類型)
  • Intent 類別

下文根據(jù)如何在應(yīng)用的清單文件中聲明 Intent 過濾器啦桌,描述 Intent 如何與相應(yīng)的組件匹配溯壶。

Intent 匹配

通過 Intent 過濾器匹配 Intent及皂,這不僅有助于發(fā)現(xiàn)要激活的目標(biāo)組件,還有助于發(fā)現(xiàn)設(shè)備上組件集的相關(guān)信息且改。 例如验烧,主頁應(yīng)用通過使用指定ACTION_MAIN 操作和 CATEGORY_LAUNCHER 類別的 Intent 過濾器查找所有 Activity,以此填充應(yīng)用啟動器又跛。

您的應(yīng)用可以采用類似的方式使用 Intent 匹配碍拆。PackageManager 提供了一整套 query...() 方法來返回所有能夠接受特定 Intent 的組件。此外慨蓝,它還提供了一系列類似的 resolve...() 方法來確定響應(yīng) Intent 的最佳組件感混。 例如,[queryIntentActivities()](http://developer.android.youdaxue.com/reference/android/content/pm/PackageManager.html#queryIntentActivities(android.content.Intent, int)) 將返回能夠執(zhí)行那些作為參數(shù)傳遞的 Intent 的所有 Activity 列表菌仁,而 [queryIntentServices()](http://developer.android.youdaxue.com/reference/android/content/pm/PackageManager.html#queryIntentServices(android.content.Intent, int)) 則可返回類似的服務(wù)列表浩习。這兩種方法均不會激活組件,而只是列出能夠響應(yīng)的組件济丘。 對于廣播接收器,有一種類似的方法: [queryBroadcastReceivers()](http://developer.android.youdaxue.com/reference/android/content/pm/PackageManager.html#queryBroadcastReceivers(android.content.Intent, int))洽蛀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末摹迷,一起剝皮案震驚了整個濱河市郊供,隨后出現(xiàn)的幾起案子驮审,更是在濱河造成了極大的恐慌地来,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缆镣,死亡現(xiàn)場離奇詭異董瞻,居然都是意外死亡睬澡,警方通過查閱死者的電腦和手機(jī)斗躏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進(jìn)店門云稚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來燕雁,“玉大人,你說我怎么就攤上這事〗鹱伲” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵奕锌,是天一觀的道長。 經(jīng)常有香客問我辽话,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任冗锁,我火速辦了婚禮箍邮,結(jié)果婚禮上摔敛,老公的妹妹穿的比我還像新娘刹悴。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布解愤。 她就那樣靜靜地躺著,像睡著了一般乎莉。 火紅的嫁衣襯著肌膚如雪送讲。 梳的紋絲不亂的頭發(fā)上奸笤,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機(jī)與錄音哼鬓,去河邊找鬼监右。 笑死,一個胖子當(dāng)著我的面吹牛异希,可吹牛的內(nèi)容都是我干的健盒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼宠互,長吁一口氣:“原來是場噩夢啊……” “哼味榛!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起予跌,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤搏色,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后券册,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體频轿,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年烁焙,在試婚紗的時候發(fā)現(xiàn)自己被綠了航邢。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡骄蝇,死狀恐怖膳殷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情九火,我是刑警寧澤赚窃,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站岔激,受9級特大地震影響勒极,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜虑鼎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一辱匿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧炫彩,春花似錦匾七、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至划址,卻和暖如春扔嵌,著一層夾襖步出監(jiān)牢的瞬間限府,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工痢缎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胁勺,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓独旷,卻偏偏與公主長得像署穗,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嵌洼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評論 2 355

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