Intent和IntentFilter詳解

來源:互聯網
上載者:User

  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()方法, 該方法存在多個重載方法, 可用於攜帶基礎資料型別 (Elementary Data Type)及其數組, 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"。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.