Android開發教程:理解Intent和Intent Filter

在Android 幫助文檔中,Intent的介紹爲An intent is an abstract description of an operation to be performed,意思是一個Intent是對一個即將進行的操作的抽象,Intent的字面意識就是”意圖”,Android應用程序中的三種其他應用程序基本組件——Activity, Service和Broadcast Receiver,都是使用稱爲intent的消息來”激活”的。對於向這三種組件發送intent有不同的機制:

使用Context.startActivity() 或 Activity.startActivityForResult(), 傳入一個intent來啓動一個Activity. 使用 Activity.setResult(), 傳入一個intent來從Activity中返回結果.
將intent對象傳給Context.startService()來啓動一個Service或者傳消息給一個運行的Service. 將intent對象傳給 Context.bindService()來綁定一個Service.
將intent對象傳給 Context.sendBroadcast(), Context.sendOrderedBroadcast(),或者Context.sendStickyBroadcast()等廣播方法,則它們被傳給 Broadcast Receiver.
在上述三種情況下, Android系統會自己找到合適的Activity, Service, 或者 Broadcast Receivers來響應Intent. 三者的Intent相互獨立互不干擾.也許有人會問,比如說在Android中啓動另一個Activity完全可以直接使用Context.startActivity(Class startClass)的方式來啓動一個Activity,爲什麼還需要使用Intent,不有點”脫褲子放屁”——多此一舉嗎?其實這種方法雖然簡單,去背離了Android設計的初衷,Android使用Intent封裝程序的”調用意圖”,不管是啓動一個Activity或是一個Service或者是啓動一個BroadcastReceiver,都可以使用統一的Intent這種”啓動意圖”,這樣就使用了一致的編程模型,也是一種高層次的”解耦”。

1、Intent簡介

Intent代表了Android應用的啓動”意圖”,Android應用將會根據Intent來啓動指定組件,至於到底啓動哪個組件,則取決於Intent的各個屬性。下面就來介紹一下Intent的各種發展,以及Android如何根據不同屬性來啓動相應的組件。Intent是由Component、Action、Data、Category、Extra及Flag六部分組成的,接下來將分別對其進行詳細介紹。

(1)組件名稱

組件名稱實際上就是一個ComponentName對象,用於標識唯一的應用程序組件,即指明瞭期望的Intent組件,這種對象的名稱是由目標組件的類名與目標組件的包名組合而成的。在Intent傳遞過程中,組件名稱是一個可選項,當指定它時,便是顯式的Intent消息,我們稱爲“顯示意圖”,當不指定它時,Android系統則會根據其他信息及IntentFilter的過濾條件選擇相應的組件,我們稱之爲 “隱式意圖”

  1. //創建一個ComponentName對象
  2. ComponentName componentName = new ComponentName(
  3. IntentDemoActivity.this, SecondActivity.class);
  4. Intent intent = new Intent();
  5. //設置Intent的Component屬性
  6. intent.setComponent(componentName);
  7. //啓動SecondActivity
  8. startActivity(intent);

上面的代碼其實完全可以簡化爲:

  1. Intent intent = new Intent(IntentDemoActivity.this, SecondActivity.class);
  2. //啓動SecondActivity
  3. startActivity(intent);

(2)Action

Action實際上就是一個描述了Intent所觸發動作名稱的字符串,在Intent類中,已經定義好多字符串常量來表示不同的Action,當然,開發人員也可以自定義Action,其定義規則同樣非常簡單。動作名必須是獨一無二的字符串,所以,一個好的習慣是使用基於Java包的命名方式的命名系統。

系統定義的Action常量有很多,下面只列出其中一些較常見的。

ACTION_CALL,撥出Data裏封裝的電話號碼。
ACTION_EDIT,打開Data裏指定數據所對應的編碼程序。
ACTION_VIEW,打開能夠顯示Data中封裝的數據的應用程序。
ACTION_MAIN,聲明程序的入口,該Action並不會接收任何數據,同時結束後也不會返回任何數據。
ACTION_BOOT_COMPLETED,BroadcastReceiver Action的常量,表明系統啓動完畢。
ACTION_TIME_CHANGED,BroadcastReceiver Action的常量,表示系統時間通過設置而改變。

  1. //聲明一個Intent對象
  2. Intent intent = new Intent();
  3. /**
  4. * 設置Action屬性,這裏是跳到撥號界面
  5. * ACTION_DIAL = "android.intent.action.DIAL";
  6. */
  7. intent.setAction(Intent.ACTION_DIAL);
  8. startActivity(intent);

Action很大程度上決定了Intent的另外部分的結構, 就像一個方法名決定了它接受的參數和返回值一樣. 因此, 最好給Action一個最能反映其作用的名字.一個Intent對象中的Action是使用getAction()和setAction()來讀寫的.

(3)Data

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

  1. //聲明一個Intent對象
  2. Intent intent = new Intent();
  3. /**
  4. * 設置Action屬性,這裏是跳到撥號界面
  5. * ACTION_DIAL = "android.intent.action.DIAL";
  6. */
  7. intent.setAction(Intent.ACTION_DIAL);
  8. Uri uri = Uri.parse("tel:0-123-456-789");
  9. intent.setData(uri);
  10. startActivity(intent);

(4)Category

Category是對目標組件類別信息的描述。同樣作爲一個字符串對象,一個Intent中可以包含多個Category。與Category相關的方法有三個,addCategory添加一個Category,removeCategory刪除一個Category,而getCategories得到一個Category。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。

一個Intent最多隻能包含一個Action屬性,但是一個Intent中可以包含多個Category屬性。

(5)Extra

Extra中封裝了一些額外的附加信息,這些信息是以鍵值對的形式存在的。Intent可以通過putExtras()與getExtras()方法來存儲和獲取Extra。在Android系統的Intent類中,同樣對一些常用的Extra鍵值進行了定義,如下所示。

EXTRA_BCC,裝有郵件密送地址的字符串數組。
EXTRA_EMAIL,裝有郵件發送地址的字符串數組。
EXTRA_UID,使用ACTION_UID_REMOVED動作時,描述刪除用戶的id。
EXTRA_TEXT,當使用ACTION_SEND動作時,描述要發送文本的信息。

(6)Flag

一些有關係統如何啓動組件的標誌位,Android同樣對其進行了封裝。

2.IntentFilter的簡介

IntentFilter實際上相當於Intent的過濾器,一個應用程序開發完成後,需要告訴Android系統自己能夠處理哪些隱形的Intent請求,這就需要聲明IntentFilter。IntentFilter的使用方法實際上非常簡單,僅聲明該應用程序接收什麼樣的Intent請求即可。

IntentFilter過濾Intent時,一般是通過Action、Data及Category三方面進行監測的。接下來分別對這三方面進行介紹。

(1)檢查Action

一個Intent只能設置一種Action,但是一個IntentFilter卻可以設置多個Action過濾。當IntentFilter設置了多個Action時,只需一個滿足即可完成Action驗證。當IntentFilter中沒有說明任何一個Action時,那麼任何的Action都不會與之匹配。而如果Intent中沒有包含任何Action,那麼只要IntentFilter中含有Action時,便會匹配成功。

(2)檢查Data

數據的監測主要包含兩部分,即數據的URI及數據類型,而數據URI又被分成三部分進行匹配(scheme、authority、path),只有這些全部匹配時,Data的驗證纔會成功。

(3)檢查Category

IntentFilter同樣可以設置多個Category,當Intent中的Category與IntentFilter中的一個Category完全匹配時,便會通過Category的檢查,而其他的Category並不受影響。但是當IntentFilter沒有設置Category時,只能與沒有設置Category的Intent相匹配。

發佈了24 篇原創文章 · 獲贊 52 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章