Android應用開發學習筆記之Intent

Intent是什麼呢?來看Android官網上的定義:

An intent is an abstractdescription of an operation to be performed. It can be used with startActivity tolaunch an Activity, broadcastIntent tosend it to any interestedBroadcastReceiver components,and startService(Intent) or bindService(Intent,ServiceConnection, int) tocommunicate with a background Service.

An Intent provides afacility for performing late runtime binding between the code in differentapplications. Its most significant use is in the launching of activities, whereit can be thought of as the glue between activities. It is basically a passivedata structure holding an abstract description of an action to be performed.

一、Intent的屬性構成

Android會根據Intent來啟動相應的組件,至於啟動哪個組件,則取決於Intent中包含的屬性。理論上,Intent可以包含如下屬性:Component name、Action、Data、Category、Extra、Flags。下面我們來分別看這些屬性的用法:

 

1、Component name

Component name屬性指明用來處理這個Intent的組件的名稱,它是一個ComponentName類對象。Componentname是一個Intent的可選屬性。如果設置瞭這個屬性,那麼該Intent將會被發送給Component name指定的組件,這個Intent被稱為“顯式Intent”。如果沒有設置Component name屬性,則Android會使用Intent的其它屬性決定合適的發送目標組件,這個Intent被稱為“隱式Intent”。

Component name屬性可以通過Intent類的setComponent()、setClass()或者setClassName()三個成員函數設置,可以通過getComponent()成員函數讀取。例如:

 
 

 //創建一個ComponentName對象  
ComponentNamecomponentName = new ComponentName( 
FirstActivity.this,SecondActivity.class); 
Intentintent = new Intent(); 
//設置Intent的Component屬性  
intent.setComponent(componentName); 
//啟動SecondActivity  
startActivity(intent); 

        //創建一個ComponentName對象
        ComponentNamecomponentName = new ComponentName(
        FirstActivity.this,SecondActivity.class);
        Intentintent = new Intent();
        //設置Intent的Component屬性
        intent.setComponent(componentName);
        //啟動SecondActivity
        startActivity(intent);

上面的代碼可以簡化為:

 

 Intent intent = new Intent(FirstActivity.this,SecondActivity.class); 
//啟動SecondActivity  
startActivity(intent); 

        Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
        //啟動SecondActivity
        startActivity(intent);

 

2、Action

Action屬性表示Intent所觸發的目標組件將要執行的動作。在Broadcast Intent中,Action用來表示已經發生即將報告給目標組件的動作。在Intent類中,已經定義好許多Action常量,開發者也可以自定義Action,自定義Action的名稱必須是獨一無二的字符串,所以,一個好的習慣是使用基於Java包的命名方式。

Action可以通過Intent類的setAction()成員函數進行設置,通過getAction()成員函數進行讀取。看下面的例子:

  


 //聲明一個Intent對象  
Intentintent = new Intent(); 
//設置Action屬性,ACTION_DIAL表示跳到撥號界面  
intent.setAction(Intent.ACTION_DIAL); 
startActivity(intent); 

//聲明一個Intent對象
Intentintent = new Intent();
//設置Action屬性,ACTION_DIAL表示跳到撥號界面
intent.setAction(Intent.ACTION_DIAL);
startActivity(intent);



3、Data

Data屬性是對Action指定的動作要操作的數據的封裝,包括動作要操作的數據的URI以及MIME類型。不同類型的Action會有不同的Data封裝,例如:如果Action是ACTION_EDIT,則Data應該是包含用來編輯文檔的URI。如果Action是ACTION_CALL,則Data應該是包含號碼的tel:URI。如果Action是ACTION_VIEW,則Data應該是http:URI。

顯示圖片的組件不應該拿來播放音頻,所以除瞭數據的URI外,數據的類型也很重要。在很多情況下,數據類型可以從URI中推斷,尤其是content:URI,它表示數據存在於設備上並由ContentProvider控制,但是,如果有必要,Data中除瞭數據的URI外,還可以顯式的包含其MIME類型。

我們可以通過Intent類的setData()成員函數設置數據的URI,通過setType()成員函數設置數據的MIME類型,也可以通過setDataAndType()成員函數同時設置數據URI和MIME類型。可以通過getData()成員函數取得數據URI,通過getType()成員函數讀取MIME類型。

 

4、Category

Category屬性描述瞭用來處理這個Intent的目標組件所屬的類別。一個Intent最多隻能包含一個Action屬性,但是可以具有多個Category屬性。與Action類似,Intent類也預定義瞭一些Category常量。

我們可以通過Intent類的addCategory()成員函數添加一個Category屬性,通過removeCategory()成員函數刪除一個Category屬性,通過getCategory()成員函數獲得當前對象中包含的全部Category屬性。

 

5、Extras

Extras屬性封裝瞭一些額外的附加信息,這些信息是以鍵值對的形式存在。

就象一些Action與特定類型的Data URI匹配一樣,有些Action與特定的Extras匹配。例如,Action為ACTION_HEADSET_PLUG,則Extras用state來表示耳機是否被插入,用name表示耳機的類型。再比如,如果Action為ACTION_TIMEZONE_CHANGED,則Extras用time-zone來表示新時區。

Intent類定義瞭多個putXXX()方法,如putExtra(),用來設置不同類型的Extra數據。也定義瞭多個getXXX()方法,如getDoubleExtra(),用來讀取Extra數據。這些方法和Bundle類有些類似,實際上,Extra可以通過putExtras()和getExtras()方法進行Bundle的設置和讀取。

 

6、Flags

Flags屬性多數用來指示Android系統如何啟動Activity(如Activity屬於哪個Task)以及啟動後如何對待(如它是否屬於近期的Activity列表)。所有的Flags都定義在Intent類中。

 

二、Intent過濾器(Intent Filter)

能夠接收處理Intent的組件(如Activity、Service、BroadcastReceiver)必須告訴Android系統它能夠響應處理什麼樣的Intent,這可以通過在AndroidManifest.xml文件中聲明Intent過濾器(Intent Filter)實現。

IntentFilter描述該組件所能響應Intent的能力,即組件所能接收的Intent應該具有什麼樣的Action,Data或Category屬性。比如,一個網頁瀏覽器程序的IntentFilter應該聲明它所希望接收的Intent應該具有ACTION_WEB_SEARCH,以及與之相關的Data應該是網頁地址URI格式。

1、  Action測試

(1)      Intent Filter應該至少包含一個Action測試,否則將屏蔽掉所有的Intent。

(2)      如果Intent沒有定義Action屬性,則隻要Intent Filter包含一個Action測試,則這個Intent就會通過測試。

(3)      一個Intent隻能有一個Action屬性,但是一個Intent Filter可以定義多個Action測試,如果Intent的Action屬性與某一條Intent Filter的Action測試匹配,就通過測試。

 

2、  Category測試

(1)      一個Intent可以定義多個Category屬性,Intent Filter也可以包含多個Category測試,隻有當Intent的所有Category屬性在Intent Filter的Category測試中均有匹配項時,Category測試才算通過。

(2)      Intent Filter中多餘的Category測試項不會導致測試失敗。

(3)      原則上講,無論Intent Filter如何定義,沒有定義Category的Intent總是可以通過Category測試。然而,需要註意,Android默認為所有通過startActivity()方法傳遞的隱式Intent設置一個Category屬性,即android.intent.category.DEFAULT(CATEGORY_DEFAULT),所以,接收隱式Intent的Activity必須在過濾器中聲明android.intent.category.DEFAULT(包含android.intent.action.MAIN和android.intent.category.LAUNCHER設置的是一個例外。它們表明Activity作為新任務啟動並且顯示在啟動屏幕上,包含android.intent.category.DEFAULT與否均可)。

(4)      一個沒有指定任何Category測試的Intent Flilter隻會匹配沒有定義Category屬性的Intent。

 

3、  Data測試

Intent Filter的Data測試可以指定URI和數據類型(MIME類型),URI可以分為scheme、host、port和path幾個獨立的部分:scheme://host:port/path

例如:content://com.liuhaoyu.project:1000/folder/subfolder/config

其中,scheme是content,host是com.liuhaoyu.project,port是1000,path是folder/subfolder/config。

host和port一起組成瞭URI授權,如果host沒有指定,則忽略port。

這些屬性都是可選的,但是相互之間並非完全獨立。如果授權有效,則scheme必須指定。如果path有效,則scheme和授權必須指定。

當Intent的Data屬性與Intent Filter的Data測試相比較時,僅僅與Intent Filter中實際提到的URI部分相比較。例如,如果Intent Filter僅指定瞭scheme,則所有具有該scheme的URI都能匹配該Intent Filter。

 

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *