萬盛學電腦網

 萬盛學電腦網 >> 網絡編程 >> 安卓開發 >> Intent和IntentFilter詳解

Intent和IntentFilter詳解

  Intent用於啟動Activity,Service, 以及BroadcastReceiver三種組件, 同時還是組件之間通信的重要媒介。

  使用Intent啟動組件的優勢

  1, Intent為組件的啟動提供了一致的編程模型。無論想要啟動的組件是Activity,Service, 還是BroadcastReceiver,都可以使用Intent封裝啟動的意圖。

  2, 在某些時候, 應用程序只是想啟動具有某種特征的組件, 並不想和某個特定的組件耦合。使用Intent可以方便的達到這種高層次解耦的目的。

  Intent的Component屬性

  Intent對象的setComponent(ComponentNamecomp)方法用於設置Intent的Component屬性。ComponentName包含如下幾個構造器:

  ComponentName(Stringpkg, String cls)

  ComponentName(Contextpkg, String cls)

  ComponentName(Contextpkg, Class cls)

  由以上的構造器可知, 創建一個ComponentName對象需要指定包名和類名--這就可以唯一確定一個組件類, 這樣應用程序即可根據給定的組件類去啟動特定的組件。例如:

  ComponentName comp =new ComponentName(FirstActivity。this,SecondActivity。class);

  Intent intent = newIntent();

  intent。setComponent(comp);

  以上三句代碼創建了一個intent對象, 並為其指定了Component屬性, 完全等價於下面的代碼:

  Intent intent = newIntent(FirstActivity。this,SecondActivity。class);

  除了使用setComponent()之外, 還可以使用setClass(),setClassName()來顯式指定目標組件, 還可以調用getComponent()方法獲得Intent中封裝的ComponentName對象。

  當程序采用這種形式啟動組件時, 在Intent中明確的指定了待啟動的組件類, 此時的Intent屬於顯式intent, 顯式Intent應用場合比較狹窄, 多用於啟動本應用中的component,因為這種方式需要提前獲知目標組件類的全限定名。而隱式Intent則通過Intent中的action,category, data屬性指定目標組件需要滿足的若干條件, 系統篩選出滿足所有條件的component,從中選擇最合適的component或者由用戶選擇一個component作為目標組件啟動。

  如果Intent中指定了ComponentName屬性, 則Intent的其他屬性將被忽略。

  Intent的Action屬性

  action屬性是一個字符串, 代表某一種特定的動作。 Intent類預定義了一些action常量, 開發者也可以自定義action。一般來說, 自定義的action應該以application的包名作為前綴, 然後附加特定的大寫字符串, 例如"cn。xing。upload。action。UPLOAD_COMPLETE"就是一個命名良好的action。

  Intent類的setAction()方法用於設定action,getAction()方法可以獲取Intent中封裝的action。

  以下是Intent類中預定義的部分action:

  ACTION_CALL--目標組件為activity,代表撥號動作;

  ACTION_EDIT--目標組件為activity,代表向用戶顯示數據以供其編輯的動作;

  ACTION_MAIN--目標組件為activity,表示作為task中的初始activity啟動;

  ACTION_BATTERY_LOW--目標組件為broadcastReceiver,提醒手機電量過低;

  ACTION_SCREEN_ON--目標組件為broadcast,表示開啟屏幕。

  Intent的Category屬性

  category屬性也是一個字符串, 用於指定一些目標組件需要滿足的額外條件。 Intent對象中可以包含任意多個category屬性。 Intent類也預定義了一些category常量, 開發者也可以自定義category屬性。

  Intent類的addCategory()方法為Intent添加Category屬性,getCategories()方法用於獲取Intent中封裝的所有category。

  以下是Intent類中預定義的部分category:

  CATEGORY_HOME--表示目標activity必須是一個顯示homescreen的activity;

  CATEGORY_LAUNCHER--表示目標activity可以作為task棧中的初始activity,常與ACTION_MAIN配合使用;

  CATEGORY_GADGET--表示目標activity可以被作為另一個activity的一部分嵌入。

  Intent的Data屬性

  data屬性指定所操作數據的URI。 data經常與action配合使用, 如果action為ACTION_EDIT,data的值應該指明被編輯文檔的URI; 如果

  action為ACTION_CALL,data的值應該是一個以"tel:"開頭並在其後附加號碼的URI; 如果action為ACTION_VIEW,data的值應該是一個以"http:"開頭並在其後附加網址的URI。。。

  Intent類的setData()方法用於設置data屬性,setType()方法用於設置data的MIME類型,setDataAndType()方法可以同時設定兩者。可以通過getData()方法獲取data屬性的值, 通過getType()方法獲取data的MIME類型。

  Intent的Extra屬性

  通過Intent啟動一個component時, 經常需要攜帶一些額外的數據過去。攜帶數據需要調用Intent的putExtra()方法, 該方法存在多個重載方法, 可用於攜帶基本數據類型及其數組, String類型及其數組, Serializable類型及其數組,Parcelable類型及其數組, Bundle類型等。Serializable和Parcelable類型代表一個可序列化的對象, Bundle與Map類似,可用於存儲鍵值對。

  Intent的Flag屬性

  flag屬性是一個int值, 用於通知android系統如何啟動目標activity,或者啟動目標activity之後應該采取怎樣的後續操作。所有的flag都在Intent類中定義, 部分常用flag如下:

  FLAG_ACTIVITY_NEW_TASK--通知系統將目標activity作為一個新task的初始activity;

  FLAG_ACTIVITY_NO_HISTORY--通知系統不要將目標activity放入歷史棧中;

  FLAG_FROM_BACKGROUND--通知系統這個Intent來源於後台操作, 而非用戶的直接選擇。。。

  IntentFilter類

  IntentFilter類表示Intent過濾器, 大部分情況下, 每一個component都會定義一個或多個IntentFilter,用於表明其可處理的Intent。

  一般來說,component的IntentFilter應該在AndroidManifest。xml文件中定義。

  定義的方法: 在<activity>,<receiver>, <service> 元素中增加一個或多個子元素。如:

  <!-- 聲明作為程序入口的Activity-->
<activityandroid:name="。FirstActivity">

  <intent-filter>
<action android:name="android。intent。action。MAIN"/>
<category android:name="android。intent。category。LAUNCHER"/>
</intent-filter>
</activity>

  IntentFilter與隱式Intent

  android系統處理隱式Intent時, 會比較Intent和IntentFilter的action,data, category屬性, 如果以上3個屬性全都相符的話, 則IntentFilter所屬的component就可以作為目標組件的候選(存在多個符合條件的component時)。

  1。測試action屬性。 intent最多只能定義1個action, 而filter可以定義1個或多個action。

  通過action測試的條件為: filter定義了intent的action。例如intent的action為"android。intent。action。MAIN",則定義了"android。intent。action。MAIN"這個action的filter都能通過action測試(當然, filter還可以包含更多額外的action)。

  如果filter沒有定義action, 則這個filter將阻塞所有intent。如果intent沒有定義action, 那麼只要filter定義了action就可以通過action測試。

  2。測試category屬性。 intent可以任意多個category,filter也可以任意個category。通過category測試的條件為: filter定義了intent的所有category。例如intent定義了"android。intent。category。DEFAULT"和"cn。xing。intent。category。UPLOAD"這2個category,則定義了以上2個category屬性的filter才能通過測試(當然, filter還可以包含更多額外的category)。

  根據上面的規則, 如果一個intent沒有定義category,則所有filter都可以通過category測試。但是有一種例外: 以startActivity(intent)方式啟動一個activity時, 系統為會intent增加一個值為"android。intent。category。DEFAULT"的category,這就意味著每一個期望通過category測試的activity,都要在其filter中定義"android。intent。category。DEFAULT"(除了作為程序入口的activity)。

  3。測試data屬性。 intent最多只能定義1個data,filter則可以定義多個data。

  通過data測試的條件為:

  a。如果intent沒有指定data和data type,則只有沒有定義data和datetype的filter才能通過測試;

  b。如果intent定義了data沒有定義datatype, 則只有定義了相同data且沒有定義datetype的filter才能通過測試;

  c。如果intent沒有定義data卻定義了datatype, 則只有未定義data且定義了相同的datatype的filter才能通過測試;

  d。如果intent既定義了data也定義了datatype, 則只有定義了相同的data和datatype的filter才能通過測試。

  data屬性是一個URI, URI中包含scheme,host, post和path, 典型的URI為:

  scheme://host:port/path

  scheme, host, post和path都是可選的。比較2個data時, 只比較filter中包含的部分。比如filter的一個data只是指定了scheme部分, 則測試時只是比較data的scheme部分, 只要兩者的scheme部分相同, 就視為"相同的data"。

 

copyright © 萬盛學電腦網 all rights reserved