Android總結篇系列:Android Intent


Intent在Android中的重要性不言而喻。本文主要總結下Intent使用過程中需要注意的一些問題。

1.隱式Intent AndroidManifest.xml聲明時<intent-filter>相關

作為“意圖”的Intent,在AndroidManifest.xml聲明時並沒有獨立的所謂的<intent>標簽形式,而是依附於其他的應用程序組件(Activity/BroadcastReceiver/Service)存在。在顯式Intent和隱式Intent類別上,顯式Intent直接對應組件名稱,隱式Intent則對應組件聲明中的子節點<intent-filter>而存在。

<intent-filter>聲明時需要注意如下幾點:

1).<intent-filter>意為"intent匹配器",主要能夠通過此“intent匹配器”的目標組件,都是“意圖”的目標對象,對於啟動Activity的隱式Intent,如果有多個目標Activity均可滿足,將以列表彈框彈出以供用戶選擇具體啟動對象。在<intent-filter>聲明時,主要包括<action>,<category>和<data>子標簽。

2).<action>作為“意圖”的具體動作,在<intent-filter>中是必須要有的,一個<intent-filter>聲明中可以有多個<action>子標簽,表示可以匹配多個不同的相應intent action,action的具體命名最好以包名開頭,以確保action的唯一性;

3).<category>作為"意圖"的類別,針對隱式Activity組件,action在<intent-filter>中也是必須要有的。默認情況下,以隱式Intent方式啟動Activity時系統會自動加上category “android.intent.category.DEFAULT”。這樣,就導致<intent-filter>中必須至少包含有<category android:name="android.intent.category.DEFAULT" />的聲明。當且僅當如下情況除外:

1 <action android:name="android.intent.action.MAIN" /> 2 <category android:name="android.intent.category.LAUNCHER" />

下面是關於Android文檔中關於category.DEFAULT具體警示:

Note: In order to receive implicit intents, you must include the CATEGORY_DEFAULT category in the intent filter. The methods startActivity() and startActivityForResult() treat all intents as if they declared the CATEGORY_DEFAULT category. If you do not declare this category in your intent filter, no implicit intents will resolve to your activity.
Android automatically applies the the CATEGORY_DEFAULT category to all implicit intents passed to startActivity() and startActivityForResult(). So if you want your activity to receive implicit intents, it must include a category for "android.intent.category.DEFAULT" in its intent filters (as shown in the previous <intent-filter> example.

同樣的,一個<intent-filter>聲明中可以有多個<category>子標簽。

4).一個Activity/BroadcastReceiver/Service組件聲明中可以包含多個<intent-filter>標簽,匹配時,針對單個的<intent-filter>依次進行匹配,總體原則是,單個<intent-filter>標簽內部,各子標簽應能夠包含代碼中intent各條件,可以多余但不能少。

 

2.代碼中使用Intent啟動其他的應用程序組件(Activity/BroadcastReceiver/Service)

1).對於顯式Intent,直接指定目標組件的類名,系統會在當前App內部Intent到目標組件;

2).一個Intent中既用了顯式Intent,同時又用了隱式Intent,直接以顯式Intent為准;

3).隱式Intent必須通過如setAction(..)方法指定action,有此可見,隱式Intent代碼中action唯一,通過addCategory (..)方法指定類別,由於category可以有多個;

4).App內部的Service啟動最好使用顯式Intent,原因Android文檔中描述:

To ensure your app is secure, always use an explicit intent when starting a Service and do not declare intent filters for your services. Using an implicit intent to start a service is a security hazard because you cannot be certain what service will respond to the intent, and the user cannot see which service starts. Beginning with Android 5.0 (API level 21), the system throws an exception if you call bindService() with an implicit intent.

有此可見:Android 5.0開始,跨App的bindService將不再有效。

5).鑒於廣播接收器本身就是由來解耦,因此,發送廣播時只能使用隱式Intent;

6).當指定的Activity組件沒有找到時,會拋出ActivityNotFoundException異常並直接崩潰,此時可以通過resolveActivity(..)方式先判斷下:

1 if (intent.resolveActivity(getPackageManager()) != null) { 2  startActivity(intent); 3 }

7).判斷兩個Intent“意圖”是否相同,使用filterEquals(intent)方法,注意只包括intent匹配時的描述信息,並不如extra和flag等額外信息。

filterEquals(Intent other) Determine if two intents are the same for the purposes of intent resolution (filtering). That is, if their action, data, type, class, and categories are the same. This does not compare any extra data included in the intents.
filterHashCode()
Generate hash code that matches semantics of filterEquals().

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM