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

Intent對於Android應用的作用

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

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

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

設置該Activity可在車載環境下使用

 

下面是一個返回桌面的例子:

private void fackBackHome(){

    Intent intent = new Intent();

    intent.setAction(Intent.ACTION_MAIN);

    intent.addCategory(Intent.CATEGORY_HOME);

    startActivity(intent);

}

 

 

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章