1. 程式人生 > >Android中的Intent和Intent-Filter詳解(一)

Android中的Intent和Intent-Filter詳解(一)

Intent對於Android應用的作用

Intent,翻譯過來是“意圖”,它是對Android應用程式“意圖”的封裝。例如ActivityA想啟動ActivityB,那麼“想啟動ActivityB”就是ActivityA的意圖;ActivityA想啟動ServiceA,“想啟動ServiceA”就是ActivityA的意圖。

至於Android為什麼不直接提供一個類似startActivity(Class activityClass)的方法來移動一個Activity,是因為這樣做會背離Android的設計理念,造成一種硬編碼耦合,不利於高層次的解耦。而Intent提供的程式設計模型,可以讓應用程式只啟動具有某種特徵額元件,不會造成元件(Activity

ServiceContentProvider)之間的耦合。

Intent不僅可以封裝應用程式需要啟動某個元件的“意圖”,還可以作為應用元件之間通訊的重要媒介。例如兩個Activity之間可以通過Bundle物件交換資料,而Intent剛好可以攜帶Bundle物件。

Intent物件如何啟動系統元件

Android應用程式包含三種重要元件:ActivityServiceBroadcastReceiver,應用程式採用了一致的方式來啟動他們——都是依靠Intent來進行啟動的,Intent就封裝了程式想要啟動程式的意圖,不僅如此,Intent還可用於與被啟動元件交換資訊。

下表顯示一部分使用Intent

啟動不同元件的方法:

元件型別

啟動方法

Activity

startActivity(Intent i)

startActivityForResult(Intent intent, int requestCode)

Service

ComponentName startService(Intent service)

boolean bindService(Intent service, ServiceConnection conn, int flags)

BroadcastReceiver

sendBroadcast(Intent intent)

sendBroadcast(Intent intent, String receiverPermission)

sendOrderedBroadcast(Intent intent, String receiverPermission)

Intent物件大致包含Component, Action, Category, Data, Type, ExtraFlag7中屬性,其中Component用於明確指定需要啟動的目標元件,而Extra用於攜帶需要交換的資料。下面詳細介紹Intent物件各屬性的作用。

Intent的屬性及Intent-Filter配置

我們知道Intent是用來封裝程式的啟動意圖的,但到底啟動哪個元件,則取決於Intent的各個屬性。

首先舉個例子,有一個女孩兒要找男朋友,此時有兩種方式來表達她的意圖:

  • 明確指出要找xxx做她的男朋友,比如找博主我^_^

  • 指出要找做男朋友,至於到底是誰不重要,只要是高富帥就行;

同樣,Intent封裝的意圖與之類似:

  • 顯式Intent:通過Component屬性明確指定要啟動哪個元件;

  • 隱式Intent:通過ActionCategory屬性指出需要啟動符合條件的元件;

Component屬性

該屬性用來明確指定需要啟動哪個元件,其建構函式如下:

  • ComponentName(Stringpkg, String cls):建立pkg所在包下的cls類所對應的元件;

  • ComponentName(Contextpkg, String cls):建立pkg所對應的包下的cls類所對應的元件;

  • ComponentName(Contextpkg, Class<?> cls):建立pkg所對應的包下的cls類所對應的元件;

下面是例子:

ComponentNamecomponentName =newComponentName(getApplicationContext(),ActivityB.class);
Intent intent =newIntent();
intent.setComponent(intent);
startActivity(intent);

除此之外,Intent也提供了快捷的方法和建構函式:

  • setClass(Contextpkg, Class<?> cls)

  • setClassName(Contextpkg, Class<?> cls)

  • setClassName(Stringpkg, String cls)

  • Intent(Contextcontext, Class<?> cls)

下面是例子:

Intent intent1 = new Intent(getApplicationContext(), ActivityB.class);

startActivity(intent1);

Intent intent2 = new Intent();

intent2.setClass(getApplicationContext(), ActivityB.class);

startActivity(intent2);

ActionCategory屬性與Intent-Filter配置

ActionCategory屬性值都為字串,其中Action表示Intent將要完成的一個抽象動作Category用於為Action指定更加詳細的類別資訊或執行的環境,所以這兩個屬性一般會結合使用。

先通過一個例子來了解一下:

public class ActivityA extends Activity {

public static final String ACTION_TEST = "com.gisirfive.ACTION_TEST";

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

Button button = new Button(this);

button.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

Intent intent = new Intent();

intent.setAction(ACTION_TEST);

startActivity(intent);

}

});

setContentView(button);

}

}
<application
……
<activity android:name=".ActivityB">

<intent-filter>

<!--指定該Activity能響應Action為指定字串的Intent-->

<action android:name="com.gisirfive.ACTION_TEST"/>

</intent-filter>

</activity>

</application>

該例子是在ActivityA中點選按鈕,通過Action指定將要啟動的元件。從程式碼我們可以知道,startActivity()將會啟動ActivityB,但是ActivityA並不知道它會啟動ActivityB,它只知道它“想要啟動Action包含ACTION_TEST的元件,這就是它的意圖

使用隱式Intent的好處是避免了硬編碼的方式建立元件之間的互動。

上面程式中出現了Intent-Filter,我們知道它是放在元件(Android三個常用元件)裡面使用的,通常可以包含如下子元素:

  • 0個或多個<action../>元素

  • 0個或多個<category…/>元素

  • 0個或1<data …/>元素

這裡需要指出的是,雖然<intent-filter>可以包含多個Action元素,但是一個Intent物件最多隻能包含一個Action屬性,相當於“意圖只能包含一個抽象動作。相反,Intent可以包含多個CategoryIntent預設包含一個Intent.CAETGORY_DEFAULT常量,其值為android.intent.category.DEFAULT),這相當於“意圖對這個抽象動作指定特定的執行環境。

指定ActionCategory呼叫系統Activity

Intent不僅可以啟動本應用內的程式元件,也可以啟動Android系統的其他應用的程式元件,包括系統自帶的程式元件——只要許可權允許。

Android內部提供了大量標準ActionCategory常量,其中用於啟動Activity的標準Action常量及對應的字串如下:

Action常量

對應字串

簡單說明

ACTION_MAIN

android.intent.action.MAIN

應用程式入口

ACTION_VIEW

android.intent.action.VIEW

顯示指定資料

ACTION_ATTACH_DATA

android.intent.action.ATTACH_DATA

指定某塊資料將被附加到其他地方

ACTION_EDIT

android.intent.action.EDIT

編輯指定資料

ACTION_PICK

android.intent.action.PICK

從列表中選擇某項並返回所選的資料

ACTION_CHOOSER

android.intent.action.CHOOSER

顯示一個Activity選擇器

ACTION_GET_CONTENT

android.intent.action.GET_CONTENT

讓使用者選擇資料,並返回所選資料

ACTION_DIAL

android.intent.action.DIAL

顯示撥號面板

ACTION_CALL

android.intent.action.CALL

直接向指定使用者打電話

ACTION_SEND

android.intent.action.SEND

向其他人傳送資料

ACTION_SENDTO

android.intent.action.SENDTO

向其他人傳送訊息

ACTION_ANSWER

android.intent.action.ANSWER

應答電話

ACTION_INSERT

android.intent.action.INSERT

插入資料

ACTION_DELETE

android.intent.action.DELETE

刪除資料

ACTION_RUN

android.intent.action.RUN

執行資料

ACTION_SYNC

android.intent.action.SYNC

執行資料同步

ACTION_PICK_ACTIVITY

android.intent.action.PICK_ACTIVITY

用於選擇Activity

ACTION_SEARCH

android.intent.action.SEARCH

執行搜尋

ACTION_WEB_SEARCH

android.intent.action.WEB_SEARCH

執行Web搜尋

ACTION_FACTORY_TEST

android.intent.action.FACTORY_TEST

工廠測試的入口點

標準Category常量及對應的字串如下:

Category常量

對應字串

簡單說明

CATEGORY_DEFAULT

android.intent.category.DEFAULT

預設的Category

CATEGORY_BROWSABLE

android.intent.category.BROWSABLE

指定該Activity能被瀏覽器安全呼叫

CATEGORY_TAB

android.intent.category.TAB

指定該Activity作為TabActivityTab

CATEGORY_LAUNCHER

android.intent.category.LAUNCHER

Activity顯示頂級程式列表中

CATEGORY_INFO

android.intent.category.INFO

用於提供包資訊

CATEGORY_HOME

android.intent.category.HOME

設定該Activity隨系統啟動而執行

CATEGORY_PREFERENCE

android.intent.category.PREFERENCE

Activity是引數面板

CATEGORY_TEST

android.intent.category.TEST

Activity是一個測試

CATEGORY_CAR_DOCK

android.intent.category.CAR_DOCK

指定手機被插入汽車底座(硬體)時執行該Activity

CATEGORY_DESK_DOCK

android.intent.category.DESK_DOCK

指定手機被插入桌面底座(硬體)時執行該Activity

CATEGORY_CAR_MODE

android.intent.category.CAR_MODE