Android -- 再来一发Intent
之前寫過一篇Intent的博客,主要說了一下隱式意圖。?傳送門:《Android -- Intent》
Intent對象構(gòu)成???????????????????????????????????????????????????????????????????????
Component name、Action、Data、Category、Extras、Flags
Component name?????????????????????????????????????????????????????????????????????
Component name即組件名稱,是要處理這個Intent對象的組件名稱。
組件名稱對象由ComponentName類來封裝,組件名稱包含包名稱和類名稱,被聲明在AndroidManifest.xml文件中。
組件名稱通過?setComponent(),setClass(),setClassName()設(shè)置,通過getComponent()獲取。
需要注意的是Component name是一個可選項,如果被設(shè)置,那么Intent對象就顯式指定了要轉(zhuǎn)向的組件,如果沒有被設(shè)置,則Intent對象需要根據(jù)其他信息進(jìn)行篩選查找。
Action?????????????????????????????????????????????????????????????????????????????????
Action是指Intent要完成的動作,是一個字符串常量。
Intent類中有很多預(yù)定義的常量,為了一些通常的動作;還有一些定義在Android API的其他地方。也可以自己定義Action常量,自定義的常量需要加上你的應(yīng)用的包名作為前綴。
Action在很大程度上決定了Intent的其他部分是如何構(gòu)造的,尤其是 data 和 extras域。(就好像函數(shù)名會決定著參數(shù)值和返回值一樣。)所以Action的名字應(yīng)該盡可能具體,并且它們應(yīng)該和Intent中的其他域緊密結(jié)合。
使用 setAction() 和 getAction()來設(shè)置和讀取Action屬性。
Data???????????????????????????????????????????????????????????????????????????????????
Data屬性是執(zhí)行動作的URI和MIME類型,不同的動作有不同的數(shù)據(jù)規(guī)格。
比如,Action是ACTION_EDIT時,數(shù)據(jù)域?qū)⑹俏臋n的URI;Action是ACTION_CALL時,數(shù)據(jù)域是 tel: URI ,帶有要撥打的電話號碼;如果Action是 ACTION_VIEW,則數(shù)據(jù)域是http: URI。
當(dāng)匹配intent和能夠處理intent所帶的數(shù)據(jù)的組件時,知道數(shù)據(jù)類型(MIME類型)是很重要的。比如,一個展示圖像的組件不應(yīng)該被叫去播放一個音頻。
很多情況下,從URI可以看出數(shù)據(jù)類型,比如content: URIs,表示數(shù)據(jù)是在設(shè)備上,但是是由content provider控制。
數(shù)據(jù)類型也可以顯式指定,比如setData()方法指定數(shù)據(jù)為URI,setType() 指定為MIME type,setDataAndType() 指定它既為URI又為MIME type。讀取的時候URI用getData(),MIME type用getType()。
Category??????????????????????????????????????????????????????????????????????????????
Category是一個字符串,提供了額外的信息,有關(guān)于能夠處理這個Intent對象的組件種類。
一個Intent對象中可以包含任意數(shù)量的category描述信息。
與category相應(yīng)的方法有添加addCategory()、移除removeCategory() 和獲取所有category getCategories() 。
Extras?????????????????????????????????????????????????????????????????????????????????
傳遞給Intent的額外數(shù)據(jù),以Bundle的形式定義,就是一些鍵值對。就好像一些動作和特定的數(shù)據(jù)URI對應(yīng),一些動作和特定的extras對應(yīng)。
比如ACTION_TIMEZONE_CHANGED intent對象有一個 "time-zone"的extra來確認(rèn)新的時區(qū);
ACTION_HEADSET_PLUG有一個"state" extra表示耳機(jī)是否插入,還有一個 "name" extra關(guān)于耳機(jī)類型;
如果你要設(shè)計一個SHOW_COLOR動作,那么extra中應(yīng)該包含顏色值。
Intent對象有一系列的putXXX()函數(shù)用于放入各種數(shù)據(jù)類型,相應(yīng)的也有一系列的getXXX()函數(shù)用于讀取數(shù)據(jù)。
實際上,數(shù)據(jù)可以被作為一個Bundle對象被使用,利用 putExtras() 和 getExtras() 方法。
Flags??????????????????????????????????????????????????????????????????????????????????
各種類型的Flag。很多是用來指定Android系統(tǒng)如何啟動activity,還有啟動了activity后如何對待它。所有這些都定義在Intent類中。
Intent filter??????????????????????????????????????????????????????????????????????????
為了告知系統(tǒng)哪一些隱式的intent可以被處理,activity,service和broadcast receiver擁有一個或多個intent filter。
每一個filter描述了組件的一種能力,和一個這個組件愿意接收的intent的集合。它實際上的效果是過濾了特定類型的intent,將不想要的intent排除在外,但是也只能排除不想要的隱式類型的intent,顯式的intent可以直接被傳遞到它的目標(biāo)對象,不管它包含什么,filter是不會被查詢的。
但是一個隱式的intent只能在能夠通過這個組件的filter之一的時候傳遞到這個組件。
一個組件對于它可以做的各種工作擁有各種獨立的filter。
一個intent filter就是一個IntentFilter類的對象,但是,由于Android系統(tǒng)必須在啟動一個組件前知道它的能力,intent filter通常不是在Java代碼中建立的,而是在應(yīng)用的manifest文件中(AndroidManifest.xml),作為<intent-filter> 元素。
一個例外的情況就是broadcast receiver的filter,它們是通過Context.registerReceiver()方法動態(tài)注冊的,它們將會被直接作為IntentFilter對象創(chuàng)建。
當(dāng)一個Intent對象和一個intent filter進(jìn)行測試時,Intent對象中只有三個方面會被參考:
?
- action
- data(URI和數(shù)據(jù)類型)
- category
?
當(dāng)決議那個組件接收intent時,extras和flags是不起作用的。
一個filter含有與Intent對象中的action,data,category平行的域,一個隱式的intent將會測試所有這三個域。
為了傳遞到含有filter的組件,intent對象必須通過所有這三個測試。
如果其中的一個測試失敗了,Android系統(tǒng)將不會把這個intent對象傳遞到這個組件,至少不會是基于那個filter的組件。
然而,由于一個組件可以擁有多個intent filter,一個intent對象可能沒有通過其中的一個filter,但是它可能通過另一個。
Code Action???????????????????????????????????????????????????????????????????????????
在manifest中,<intent-filter>元素將動作作為其<action>子元素列出:
<intent-filter . . . ><action android:name="com.example.project.SHOW_CURRENT" /><action android:name="com.example.project.SHOW_RECENT" /><action android:name="com.example.project.SHOW_PENDING" />. . . </intent-filter>一個filter可以列出多個動作,這個列表不能為空,即一個filter應(yīng)該至少包含一個動作,否則它將會阻擋任何的intent。
為了通過這個測試,intent對象中指定的動作應(yīng)該和列出的動作之一匹配,如果intent對象或filter沒有指定動作,結(jié)果將會如下:
1.如果是filter沒有列出任何動作,沒有東西讓intent來匹配,所以所有的intent都將會在測試中失敗。沒有任何intent可以通過這個測試。
2.另一方面,如果一個intent對象沒有指定動作,那它將自動地通過測試。(只要filter中含有至少一個動作)。
Code Category????????????????????????????????????????????????????????????????????????
<intent-filter>也將分類作為其子元素列出,如
<intent-filter . . . ><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" />. . . </intent-filter>如果一個intent對象想通過category,那么在intent對象中的每一個分類都必須和filter中的一個分類匹配。
Filter可以列出多余的分類,但是不能忽略intent中的任何一個分類。
原則上來說,一個不帶有任何category的intent對象應(yīng)該總是能夠通過測試。但是有一個例外,Android將所有傳入startActivity()方法的隱式intent看作它們至少含有一個category: "android.intent.category.DEFAULT" (the CATEGORY_DEFAULT constant)。
所以,想要收到隱式intent對象的activity必須在它們的intent filter中包含 "android.intent.category.DEFAULT"?。(包含"android.intent.action.MAIN" 和 "android.intent.category.LAUNCHER"的filter是一個例外,它們可以包含"android.intent.category.DEFAULT",但是它們沒有必要這樣做。)
Code Data?????????????????????????????????????????????????????????????????????????????
和動作和分類一樣,數(shù)據(jù)也是作為子標(biāo)簽出現(xiàn),也可以不出現(xiàn)或出現(xiàn)多次。如:
<intent-filter . . . ><data android:mimeType="video/mpeg" android:scheme="http" . . . /> <data android:mimeType="audio/mpeg" android:scheme="http" . . . />. . . </intent-filter>每一個<data>元素可以指定一個URI和一個數(shù)據(jù)類型(MIME media type)。
每一個URI包含下列屬性:scheme, host, port, path??? (如:scheme://host:port/path)
當(dāng)一個intent對象中的URI和filter中的URI比較時,它僅僅和filter中實際提到的URI部分進(jìn)行比較。比如,一個filter僅僅指定了scheme,那么所有有那個scheme的URI都和這個filter匹配。
Filter中的path可以包含通配符(wildcards)。
<data>元素中的type屬性指定了數(shù)據(jù)的MIME type,它在filter中比URI更常見。
Intent對象和filter都可以使用通配符*去表示子類型,如"text/*" or "audio/*" — indicating any subtype matches。
?
數(shù)據(jù)測試需要測試URI和數(shù)據(jù)類型,規(guī)則如下:
a.一個intent對象,如果既不包含URI,也不包含數(shù)據(jù)類型,那么僅當(dāng)filter也都不包含時,可以通過測試。
b.如果一個intent對象僅包含一個URI,不包含數(shù)據(jù)類型,(并且從URI中也不能得到數(shù)據(jù)類型),那么僅當(dāng)這個URI和filter中的URI匹配,并且filter中也不包含數(shù)據(jù)類型時,可以通過測試。(This will be the case only for URIs like mailto: and tel: that do not refer to actual data.)
c.一個intent對象如果只包含數(shù)據(jù)類型不包含URI,那么僅當(dāng)filter包含同樣的數(shù)據(jù)類型并且不包含任何URI時可以通過測試。
d.一個intent對象如果同時包含URI和數(shù)據(jù)類型,(或者是可以從URI中推斷出的數(shù)據(jù)類型),那么僅當(dāng)它的數(shù)據(jù)類型和filter中的一個數(shù)據(jù)類型匹配時它可以通過數(shù)據(jù)類型部分的測試,如果要通過URI部分的測試,一種情況是它的URI和filter中的匹配,另一種情況是intent包含有content:或者file:URI而filter不包含URI。換句話說,如果一個filter只指定了數(shù)據(jù)類型,組件是預(yù)定義地支持content:或者file:數(shù)據(jù)的。
如果一個intent可以通過多個activity或service的filter,用戶將被詢問,到底要選擇哪個組件來啟動;如果沒有目標(biāo)被發(fā)現(xiàn),將會產(chǎn)生一個異常。
我是天王蓋地虎的分割線 ? ? ? ? ?
本文轉(zhuǎn)自我愛物聯(lián)網(wǎng)博客園博客,原文鏈接:http://www.cnblogs.com/yydcdut/p/3933997.html,如需轉(zhuǎn)載請自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的Android -- 再来一发Intent的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: glob及IO重定向
- 下一篇: 物联网时代如何管理上百万设备?找风河DL