標籤:android style http java color 使用
Intent可以分為兩種:顯式Intent和隱式Intent;
顯式Intent:通過組件名字欄位指定目標組件;因為開發人員通常不知道其它應用程式的組件名字,所以,顯式Intent通常用於應用程式內部訊息傳遞;例如:一個Activity啟動從屬的服務或啟動一個同層級的Activity;
隱式Intent:不指定目標組件的名字(組件名字欄位是空);隱式Intent經常用於啟用其它應用程式中的組件;
Android系統傳遞一個顯式Intent訊息對象到一個指定目標組件名字的執行個體,Intent訊息對象中只用組件名字內容區決定哪個組件應該獲得這個Intent訊息對象,而不用其它內容;
對於隱式Intent訊息對象來說,需要指定另外一種不同的策略;由於沒有指定目標組件名字,Android系統就必須尋找並匹配一個最合適的組件或多個合適的組件來處理這個Intent訊息對象:一個Activity或Service去執行請求動作,或一組廣播接收者去響應訊息;為了打到這個目的,Android定義了一個名為IntentFilter的Intent過濾器類來完成這個任務;IntentFilter類的執行個體通過比較Intent訊息對象中的內容和Intent過濾器來實現目標組件的尋找和匹配;每個IntentFilter執行個體描述了該組件所能響應Intent訊息對象的能力:組件希望接收什麼類型的請求行為,什麼類型的請求資料,等等;Intent過濾器執行個體關聯到潛在的接收Intent訊息對象的組件,它聲明了目標組件響應Intent訊息對象的能力,界定了目標組件所能處理的Intent訊息對象,它們開啟組件接收聲明的Intent訊息物件類型的隱式Intent;如果一個組件沒有關聯任何Intent過濾器,則它只能接收顯式Intent訊息對象,而聲明了Intent過濾器的組件則可以接收顯式的和隱式的Intent訊息對象;
IntentFilter執行個體與隱式Intent匹配時需要比較的三要素是:動作Action、資料(包括URI和MIME類型)和Category種類;而附加資訊Extras和標誌Flags在尋找匹配時不起作用;實際上,一個隱式Intent訊息對象如要能夠成功地傳遞給目標組件,就必須要通過這三個方面的檢查和匹配,如果有任何一方面不匹配,Android系統都不會將該隱式Intent訊息對象傳遞給目標組件;
Activity、Service和BroadcastReceiver為了告訴系統能夠處理哪些隱式Intent,它們可以有一個或多個Intent過濾器執行個體;每個過濾器描述組件的一種能力,即,感興趣的一組Intent訊息對象;實際上,它篩選掉不感興趣的Intent,也僅僅是不想要的隱式Intent訊息對象;一個顯式Intent訊息對象總是能夠成功地傳遞到目標組件,不管它包含什麼,也不考慮過濾器,不會進行任何尋找和匹配;但是一個隱式Intent訊息對象,僅當它能夠通過組件的過濾器之後,才能成功地傳遞給目標組件;
一個目標組件能夠做的每一件工作都有獨立的過濾器;每個過濾器都有對應的IntentFilter類的執行個體;因為Android系統在啟動一個組件之前都必須要知道這個組件的能力,但是Intent過濾器通常不在Java代碼裡面設定,而是在應用程式的資訊清單檔AndroidManifest.xml中的標籤<intent-filter>中設定;但是,有一個例外,廣播訊息接收者的過濾器可以通過函數Context.registerReceiver()動態地註冊,它直接建立一個IntentFilter類的執行個體;
一個過濾器有對應的動作Action、資料Data和種類Category;過濾器要檢查隱式Intent訊息對象的所有這三個欄位,其中任何一個欄位匹配失敗,則Android系統都不會把這個隱式Intent訊息對象傳遞給目標組件;然而因為一個組件可以有多個Intent過濾器,所以,一個隱式Intent訊息對象雖然不能通過一個過濾器的檢查,但是有可能通過另外一個過濾器的檢查;
一、動作檢查
資訊清單檔中的標籤<intent-filter>使用子標籤<action>來列出動作Action;例如:
<intent-filter ...>
<action android:name="com.test.project.ADD_BOOK" />
<action android:name="com.test.project.EDIT_BOOK" />
<action android:name="com.test.project.DELETE_BOOK" />
......
</intent-filter>
一個Intent訊息對象僅描述一個動作,而一個過濾器中可以指定多個動作,這個動作列表不可為空,一個過濾器至少要包含一個<action>子標籤,否則它將阻塞所有的Intent訊息對象;
如要通過檢查,Intent訊息對象中的動作Action必須要匹配過濾器的動作列表中的一個;如果Intent訊息對象或者過濾器的動作列表中沒有指定任何一個具體的動作Action,則會出現以下兩種情況:
1、如果過濾器沒有指定任何一個動作Action,則所有的Intent訊息對象都不會匹配成功,所有的Intent訊息對象都將匹配失敗,即,沒有任何一個Intent訊息對象能夠通過過濾器;
2、如果Intent訊息對象沒有指定任何一個動作Action,將自動通過過濾器的檢查(只要過濾器的動作列表中至少有一個動作,否則就是上面的情況了);
二、種類檢查
資訊清單檔中的標籤<intent-filter>使用子標籤<category>來列出種類Category;例如:
<intent-filter ...>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
......
</intent-filter>
一個Intent訊息對象如要通過種類檢查,則這個Intent訊息對象中的每個種類都必須匹配過濾器的種類列表中的一個;即,過濾器能夠列出額外的種類,但Intent訊息對象中的每個種類都必須能夠在過濾器的種類列表中找到,只要有一個種類在過濾器的種類列表中沒有找到,則種類檢測就認為是失敗的;
因此,原則上,如果一個Intent訊息對象中沒有指定種類,即,種類欄位為空白,那麼它總是應該通過過濾器的種類檢查,而不管過濾器中有什麼種類;但有個例外,Android系統對待所有傳遞給Context.startActivity()函數的隱式Intent訊息對象,它們至少都要包含種類"android.intent.category.DEFAULT"(對應CATEGORY_DEFAULT常量);因此,Activity如要接收隱式Intent訊息對象,就必須要在Intent過濾器中包含種類"android.intent.category.DEFAULT";
備忘:種類"android.intent.action.MAIN"標記Activity開始新的任務,種類"android.intent.category.LAUNCHER"標識啟動HOME介面;它們可以包含種類"android.intent.category.DEFAULT"到種類類表,也可以不包含;
三、資料檢查
資訊清單檔中的標籤<intent-filter>使用子標籤<data>來列出資料Data;例如:
<intent-filter ...>
<data android:mimeType="video/mpeg" android:scheme="http" .../>
<data android:mimeType="audio/mpeg" android:scheme="http" .../>
......
</intent-filter>
每個<data>標籤都包含一個資料的URI和資料的MIME類型;它有四個屬性:scheme、host、port和path,分別對應URI的每個部分;
格式如下:
scheme://host:port/path
host和port共同構成URI的憑據(authority),如果不指定host,則port也會被忽略;這四個屬性都都是可選的,它們之間並不都是我完全獨立的;如果要讓authority有意義,則scheme必須要指定;要讓path有意義,scheme和authority都必須要指定;
當檢查匹配Intent訊息對象和過濾器的URI時,只比較過濾器中出現的URI屬性;例如,如果一個過濾器僅指定了scheme,則所有此scheme的URIs都能被過濾器成功匹配;如果一個過濾器指定了scheme和authority,但是沒有指定path,則所有匹配scheme和authority的URIs都能被過濾器成功匹配,而不考慮它們的path;如果四個屬性都指定了,則都要匹配成功才算通過;然而過濾器中的path可以包含萬用字元來要求匹配path中的一部分;
<data>標籤的type屬性指定資料的MIME類型;Intent訊息對象和過濾器執行個體都可以使用萬用字元"*"來匹配子類型欄位;例如:"text/*"、"audio/*"表示任何子類型;
資料檢查既要檢查URI,也要檢查資料類型,規則如下:
規則1、一個Intent訊息對象既不包含URI,也不包含資料類型:僅當過濾器也不指定任何URI和資料類型時,才不能通過檢查;否則都能通過;
規則2、一個Intent訊息對象包含URI,但不包含資料類型:僅當過濾器也不指定任何資料類型,同時匹配它們的URI,才能通過檢查;
規則3、一個Intent訊息對象包含資料類型,但不包含URI:僅當過濾器也只指定資料類型,且與Intent訊息對象的相同,才能通過檢查;
規則4、一個Intent訊息對象既包含URI,也包含資料類型:資料類型部分,只有與過濾器中指定的資料類型之一匹配,才算通過檢查;URI部分,它的URI要出現在過濾器中,或者它有"content:"或"file:"URI,又或者過濾器沒有指定URI;換句話說,如果它的過濾器僅列出了資料類型,組件假定支援"content:"或"file:";
如果一個Intent訊息對象能夠通過多個Activity或Service的過濾,則使用者可能會被問:哪個組件被啟用?如果沒有找到目標組件,則會產生一個異常;
四、通用情況
上面最後一條規則表明組件能夠從檔案或者是內容提供者那裡擷取本機資料;因此,它們的過濾器僅列出資料類型且不必明確指出"content:"或"file:"的scheme的名字;
者是一種典型情況,一個<data>標籤像下面這樣:
<data android:mimeType="image/*" />
這個配置告訴Android系統,這個組件能夠從內容提供者那裡擷取image資料並顯示它;因為大部分可用資料由內容提供者分發,過濾器指定一個資料類型但沒有指定URI,或許最通用;
另一種通用配置是過濾器指定一個scheme和一個資料類型;例如:
<data android:scheme="http" android:type="video/*" />
這個配置告訴Android系統,這個組件能夠從網路擷取視頻資料並顯示它;