Android筆記(七十四) 詳解Intent

來源:互聯網
上載者:User

標籤:

      我們最常使用Intent來實現Activity之間的轉跳,最近做一個app用到從系統搜尋圖片的功能,使用到了intent的 setType 方法和 setAction 方法,網上搜尋一番,發現實現轉跳只是Intent功能的九牛一毛,現在對Intent功能做一個總結,以作備忘。

      我們經常使用如下方法實現一個轉跳:

Intent intent = new Inent(MainActivity.this,SecondActivity.class);startActivity(intent);

      其實這種寫法還可以寫作

Intent intent = new Intent();intent.setClass(MainActivity.this,SecondActivity.class);startActivity(intent);

 

      這種啟動方式被稱之為“顯式意圖”,因為它直接指定了意圖目標

      還有一種方式稱之為“隱式意圖”,我們不直接指定目標組件,而是通過設定Intent的各個屬性來啟動目標組件

Intent

      Intent由 ComponentName 、 Action 、 Data 、 Category 、 Extra 、 Flag 六部分來組成,Intent通過調用 setXXX() 方法來設定其對應的屬性,下面詳細介紹各個屬性

      【ComponentName】

       ComponentName 用於標識位移的應用程式組件,即指明了期望的Intent,這種對象的名稱是由目標組件的包名,與期望的類名組合而成,在Intent傳遞過程中,組件名稱是一個可選項。當指定它時,便是顯式的Intent訊息;而當不指定它時,Android系統會根據其他資訊,以及IntentFilter的過濾條件來選擇相應的組件。

      【Action】

       Action 實際上就是一個描述了Intent所出發動作名稱的字串,在Intent類中,已經定義好很多字串常量來表示不同的Action,當然開發人員也可以自訂Action

      常見的Action常量

      ACTION_CALL——播出Data裡封裝的電話號碼

      ACTION_EDIT——開啟Data裡指定資料所對應的編輯程式

      ACTION_VIEW——開啟能夠顯示Data之中封裝的資料的應用程式

      ACTION_MAIN——聲明程式入口,該Activity並不會接收任何資料,同時結束後也部會返回任何資料

      ACTION_BOOT_COMPLETED——BraodcastReceiver Action常量,表明系統啟動完畢

      ACTION_TIME_CHANGED——BraodcastReceiver Action常量,表示系統時間通過設定而改變

      更多可以查看  http://www.cnblogs.com/xs104/p/5111858.html

      因為API的更新,部分名稱會改變,但基本思路不變。

      【Data】

       Data 主要是對Intent訊息中資料的封裝,主要描述Intent的動作所操作到底資料的URI及類型。不同類型的 Action會有不同的Data封裝,例如打電話的Intent會封裝tel://格式的電話URI,而ACTION_VIEW的Intent中Data則會封裝http://格式的URI,正確的Data封裝對Intent匹配請求同樣非常重要

      【Category】

       Category 是對目標組件類別資訊的描述,同樣為一個字串對象,一個Intent中可以包含多個Category,與Category相關的方法有三個:

      1.添加一個Category——addCategory

      2.刪除一個Category——removeCategory

      3.得到一個Category——getCategory

      Android系統同樣定義了一組常量來表示Intent的不同類別,一些常見的Category常量

      CATEGORY_GADGET,表示目標Activity是可以嵌入到其他Activity中的。

      CATEGORY_HOME,表明目標Activity為HOME Activity。

      CATEGORY_TAB,表明目標Activity是TabActivity的一個標籤下的Activity。

      CATEGORY_LAUNCHER,表明目標Activity是應用程式中最先被執行的Activity。

      CATEGORY_PREFERNCE,表明目標Activity是一個喜好設定的Activity。

      【Extra】

       extra 中封裝了一些額外附加的資訊,這些資訊以索引值對的形式存在,Intent可以通過putExtras()和getExtras()方法來儲存和擷取Extra,Android系統同樣定義了一些Extra常量

      EXTRA_CC,郵件抄送人郵箱地址。

              EXTRA_EMAIL,裝有郵件發送地址的字串數組。

              EXTRA_SUBJECT,當使用ACTION_SEND動作時,描述要發送郵件的主題。

              EXTRA_TEXT,當使用ACTION_SEND動作時,描述要發送文本的資訊。

【Flags】

      android中Intent的Flags有20多種,如下

FLAG_GRANT_READ_URI_PERMISSIONFLAG_GRANT_WRITE_URI_PERMISSIONFLAG_DEBUG_LOG_RESOLUTIONFLAG_FROM_BACKGROUNDFLAG_ACTIVITY_BROUGHT_TO_FRONTFLAG_ACTIVITY_CLEAR_TASKFLAG_ACTIVITY_CLEAR_TOPFLAG_ACTIVITY_CLEAR_WHEN_TASK_RESETFLAG_ACTIVITY_EXCLUDE_FROM_RECENTSFLAG_ACTIVITY_FORWARD_RESULTFLAG_ACTIVITY_LAUNCHED_FROM_HISTORYFLAG_ACTIVITY_MULTIPLE_TASKFLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_NO_ANIMATIONFLAG_ACTIVITY_NO_HISTORYFLAG_ACTIVITY_NO_USER_ACTIONFLAG_ACTIVITY_PREVIOUS_IS_TOPFLAG_ACTIVITY_RESET_TASK_IF_NEEDEDFLAG_ACTIVITY_REORDER_TO_FRONTFLAG_ACTIVITY_SINGLE_TOPFLAG_ACTIVITY_TASK_ON_HOMEFLAG_RECEIVER_REGISTERED_ONLY

 

      但是我們常用的只有4種

FLAG_ACTIVITY_CLEAR_TOP

例如現在的棧情況為:A B C D 。D此時通過intent跳轉到B,如果這個intent添加FLAG_ACTIVITY_CLEAR_TOP 標記,則棧情況變為:A B。如果沒有添加這個標記,則棧情況將會變成:A B C D B。也就是說,如果添加了FLAG_ACTIVITY_CLEAR_TOP 標記,並且目標Activity在棧中已經存在,則將會把位於該目標activity之上的activity從棧中彈出銷毀。這跟上面把B的Launch mode設定成singleTask類似。

      

FLAG_ACTIVITY_NO_HISTORY
例如現在棧情況為:A B C。C通過intent跳轉到D,這個intent添加FLAG_ACTIVITY_NO_HISTORY標誌,則此時介面顯示D的內容,如果此時D中又跳轉到E,棧的情況變為:A B C E,此時按返回鍵會回到C,因為D根本就沒有被壓入棧中。

     

FLAG_ACTIVITY_SINGLE_TOP
和上面Activity的 Launch mode的singleTop類似。如果某個intent添加了這個標誌,並且這個intent的目標activity就是棧頂的activity,那麼 將不會建立一個執行個體壓入棧中。

 

  

FLAG_ACTIVITY_NEW_TASK
例如現在棧1的情況是:A B C。C通過intent跳轉到D,並且這個intent添加了FLAG_ACTIVITY_NEW_TASK 標 記,如果D這個Activity在Manifest.xml中的聲明中添加了Task affinity,並且和棧1的affinity不同,系統首先會尋找有沒有和D的Task affinity相同的task棧存在,如果有存在,將D壓入那個棧,如果不存在則會建立一個D的affinity的棧將其壓入。如果D的Task affinity預設沒有設定,或者和棧1的affinity相同,則會把其壓入棧1,變成:A B C D,這樣就和不加FLAG_ACTIVITY_NEW_TASK 標記效果是一樣的了。 

 

      

  注意如果試圖從非activity的非正常途徑啟動一個activity,比如從一個service中啟動一個activity,則intent必須要添加 FLAG_ACTIVITY_NEW_TASK  標記。

  更多:Intent中的Flag

 

IntenFilter

      IntentFilter 描述了一個組件願意接收什麼樣的Intent對象,Android將其抽象為android.content.IntentFilter類。在 Android 的AndroidManifest.xml 設定檔中可以通過 <intent-filter> 節點,為一個Activity指定其IntentFilter,以便告訴系統該Activity可以響應什麼類型的 Intent。這樣的Intent稱為隱式的Intent。

      當程式員使用startActivity(intent)來啟動另外一個Activity時,如果直接指定intent了對象的Component屬性,那麼Activity Manager將試圖啟動其Component屬性指定的Activity。否則Android將通過Intent的其它屬性,從安裝在系統中的所有Activity中尋找與之最匹配的一個啟動。如果沒有找到合適的Activity,應用程式會得到一個系統拋出的異常。

Intent的匹配

  Intent解析機制主要是通過尋找登入在AndroidManifest.xml中的所有IntentFilter及其中定義的Intent,最終找到匹配的Intent。在這個解析過程中,Android是通過Intent的action、type、category這三個屬性來進行判斷的,判斷方法如下:

  1 如果Intent指明定了action,則目標組件的IntentFilter的action列表中就必須包含有這個action,否則不能匹配;

  2 如果Intent沒有提供type,系統將從data中得到資料類型。和action一樣,目標組件的資料類型列表中必須包含Intent的資料類型,否則不能匹配。

  3 如果Intent中的資料不是content: 類型的URI,而且Intent也沒有明確指定它的type,將根據Intent中資料的scheme (比如 http: 或者mailto:) 進行匹配。

  同上,Intent 的scheme必須出現在目標組件的scheme列表中。

  4 如果Intent指定了一個或多個category,這些類別必須全部出現在組建的類別列表中。

  比如Intent中包含了兩個類別:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目標組件必須至少包含這兩個類別。每一個通過startActivity()方法發出的隱式Intent都至少有一個category,就是"android.intent.category.DEFAULT",

所以只要是想接收一個隱式Intent的Activity都應該包括"android.intent.category.DEFAULT" category,不然將導致 Intent 匹配失敗。

Android筆記(七十四) 詳解Intent

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.