android 之 intent

Android 包括四大組件,activity、service、broadcast、contentprovider。四大組件依靠intent 緊密聯繫在一起。所以有必要先學習一下intent。

簡介

什麼是intent,按照文檔解釋:An intent is an abstract description of anoperation to be performed。翻譯過來就是:intent 對將要執行的動作的一個抽象描述。

Intent可以用來做什麼?

1.             啓動一個activity。可以通過Context.startActivity(intent)或者startactivityforResult來啓動一個activity,且這個intent可以攜帶一些必要的數據。

2.             啓動一個service。可以通過Context.startService(intent)來啓動一個servie。或者如果service被設計爲一個C-S的接口,那麼可以通過bindServiceintent)綁定到這個service

3.             發送廣播。可以通過發送廣播,通知某些事件的發生,如系統啓動等。通過傳一個Intent到方法sendBroadcast(),sendOrderedBroadcast(), 或者sendStickyBroadcast().來發送廣播。

Intent 分類

有兩種類型的intent。分別是明確的(Explicit)和非明確(Implicit)的。

1.               明確的intent.通過完整的限定類名來描述intent。通常使用明確的intent來啓動你自己的app中的一個組件,因爲你清楚的知道其類名。如new inent(this,TestActivirty.class),Context.startActivity(intent);

2.               非明確的intent。沒有提供精確的類名,但是聲明瞭將要執行的動作(Action)以及其他數據,如Category 和data。

當使用明確的Intent來啓動一個activity或者service的時候,系統可以立刻啓動相應的組件,並把這個intent傳遞給他。當使用非明確的intent的時候,系統爲了找到合適的組件,需要掃描manifest 文件來尋找合適的組件。這是通過匹配intent Filter 進行的。

構建intent.

Intent 包含了很多信息,android系統使用這些信息來決定啓動哪些組件。主要包含以下信息:組件名稱(component name)、動作(action)、數據(data)、策略(category)。

1.     組件名稱

待要啓動的組件的名稱。這是一個可選的信息,但是它是構造明確的intent所必須需要的信息。當啓動一個service的時候,儘可能的使用明確的intent,否則很可能有意想不到的結果。可以如下構建一個intent:

        //直接構造函數構造

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

       

        Intent intent1 = new Intent();

        //通過以下三個方法構造

        intent1.setComponent(new ComponentName(packageName, className));

        intent1.setClass(this, MainActivity.class);

        intent1.setClassName(this, MainActivity.class.getCanonicalName());

2.     動作

一個String,代表將要執行的動作。如選擇或者查看、編輯。Action通常決定了intent的剩餘的部門怎麼構造,如它應該包含哪些data和extras。系統預定義了一些Action,儘可能的使用它們,你也可以定義自己的action

 

3.     數據

Data 包含兩方面的信息,URI和MIME type。前者表示數據的地址,後者表示數據的類型。有的時候URI暗含有MIME,例如contentProvider, Conten:URI.

單獨設置URI,使用方法setData,單獨設置MIME,使用setType。如果都要設置,那麼使用setDataAndType。建議使用最後一個,因爲單獨使用的時候,會把另外一個置爲null.

4.     策略

額爲信息,它說明了可以處理這個intent的組件類型。一個intent可以有任意數量的category,但是並不是必須。

CATEGORY_BROWSABLE這個activity  允許自己被一個web瀏覽器啓動來顯示被一個鏈接引用的數據,如一張圖片或者一個email

 

Intent也可以附帶那些不影響解析,啓動哪一個組件的信息,如extrasflag

5.     額外信息

這是完全自己定義的,用來向下一個組件傳遞信息。

6.     Flag

這是與task有關的變量,它影響了activity在task棧中的存在方式。

Intent注意

當 調用stattActivity(intent)的時候,如果intent 不能被解析爲一個activity,那麼就會拋出異常而程序崩潰,爲了防止這種情況,可以做以下處理

Intent intent1 = new Intent();

        if (intent.resolveActivity(getPackageManager())!=null) {

           startActivity(intent);

       }

當使用非明確的intent的時候,對於一個intent,可能有多個app的組件都可以響應,這個時候系統會彈出一個選擇列表供用戶選擇。

當然這個選擇框,也可以自定義標題。如下:

Intent intent1 = new Intent();

         Intent chooseIntent = Intent.createChooser(intent1, "請自定義選擇的標題");

        if (intent1.resolveActivity(getPackageManager())!=null) {

           startActivity(chooseIntent);

       }

接收intent 和intent Filter

對於明確的intent,總是被髮送給它確切的目標組件,而不管這個組件聲明的intent filter。

對於非明確的intent,那就需要根據在android manifest 中聲明的intent filter按照一定的規則進行匹配。每一個intent filter 都基於 Action、data和category 描述了其所能接收的intent。

下面是filter的例子,一個組件可以有多個intent filter:

<activity android:name="MainActivity">

    <!-- This activity is the main entry, should appear in app launcher -->

    <intent-filter>

        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />

    </intent-filter>

</activity>

 

<activity android:name="ShareActivity">

    <!-- This activity handles "SEND" actions with text data -->

    <intent-filter>

        <action android:name="android.intent.action.SEND"/>

        <category android:name="android.intent.category.DEFAULT"/>

        <data android:mimeType="text/plain"/>

    </intent-filter>

    <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->

    <intent-filter>

        <action android:name="android.intent.action.SEND"/>

        <action android:name="android.intent.action.SEND_MULTIPLE"/>

        <category android:name="android.intent.category.DEFAULT"/>

        <data android:mimeType="application/vnd.google.panorama360+jpg"/>

        <data android:mimeType="image/*"/>

        <data android:mimeType="video/*"/>

    </intent-filter>

</activity>

Intent解析

一個非明確的intent 需要通過intent filter 的檢測,纔可以發送到通過檢測的組件,這個檢測對於intent filter 的 action、data和category。

Action測試。一個filter中可以有0個或者多個action屬性。Intent需要匹配其中的一個,纔可以通過測試。如果filter中沒有action,那麼intent測試不通過,除非這個intent沒有添加action的描述。

Category測試。一個filter中可以有0個或者多個category。Intent也可以添加多個category。需要添加的每個category都能匹配filter 中的某個,纔可以測試通過。因此,當一個intent中沒有任何category中,總是可以測試通過。注意,android自動的爲每一個隱含的intent(用來調用startActivity 或者startactivityforesult)添加CATEGORY_DEFAULT這個category。所以activityz必須在androidmanefest文件中其對應的filter中添加此category,課可以接收非明確的intent。

Data測試。Mime type的匹配和 scheme://host:port/pathor pathPrefix or pathPattern 的匹配。類似以上。

DevGuide http://developer.android.com/guide/topics/manifest/data-element.html

 

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