Android Intent 深刻理解

什麼是Intentandroid

Intent是一種運行時綁定(run-time binding)機制,它能在程序運行過程當中鏈接兩個不一樣的組件。經過Intent,你的程序能夠向Android表達某種請求或者意願,Android會根據意願的內容選擇適當的組件來完成請求。好比,有一個Activity但願打開網頁瀏覽器查看某一網頁的內容,那麼這個Activity只須要發出WEB_SEARCH_ACTION給Android,Android就會根據Intent的請求內容,查詢各組件註冊時聲明的IntentFilter,找到網頁瀏覽器的Activity來瀏覽網頁。 
瀏覽器

Android的三個基本組件——Activity,Service和Broadcast Receiver——都是經過Intent機制激活的,不一樣類型的組件有不一樣的傳遞Intent方式:服務器

1.1 要激活一個新的Activity,或者讓一個現有的Activity作新的操做,能夠經過調用Context.startActivity()或者Activity.startActivityForResult()方法。 
app

1.2 要啓動一個新的Service,或者向一個已有的Service傳遞新的指令,調用Context.startService()方法或者調用Context.bindService()方法將調用此方法的上下文對象與Service綁定。ide

1.3 Context.sendBroadcast()、Context.sendOrderBroadcast()、Context.sendStickBroadcast()這三個方法能夠發送Broadcast Intent。發送以後,全部已註冊的而且擁有與之相匹配IntentFilter的BroadcastReceiver就會被激活。 
this

Intent一旦發出,Android都會準確找到相匹配的一個或多個Activity,Service或者BroadcastReceiver做響應。因此,不一樣類型的Intent消息不會出現重疊,即Broadcast的Intent消息只會發送給BroadcastReceiver,而決不會發送給Activity或者Service。由startActivity()傳遞的消息也只會發給Activity,由startService()傳遞的Intent只會發送給Service。spa


Intent的構成component

要在不一樣的activity之間傳遞數據,就要在intent中包含相應的內容,通常來講數據中最基本的應該包括:orm

Action:用來指明要實施的動做是什麼,好比說ACTION_VIEW, ACTION_EDIT等。具體的能夠查閱android SDK-> reference中的Android.content.intent類,裏面的constants中定義了全部的action。xml

一些經常使用的Action:

ACTION_CALL activity 啓動一個電話.
ACTION_EDIT activity 顯示用戶編輯的數據.
ACTION_MAIN activity 做爲Task中第一個Activity啓動
ACTION_SYNC activity 同步手機與數據服務器上的數據.
ACTION_BATTERY_LOW broadcast receiver 電池電量太低警告.
ACTION_HEADSET_PLUG broadcast receiver 插拔耳機警告
ACTION_SCREEN_ON broadcast receiver 屏幕變亮警告.
ACTION_TIMEZONE_CHANGED broadcast receiver 改變時區警告.

Data: 要事實的具體的數據,通常由一個Uri變量來表示

Category:一個字符串,包含了關於處理該intent的組件的種類的信息。一個intent對象能夠有任意個category。intent類定義了許多category常數.

addCategory()方法爲一個intent對象增長一個category,
removeCategory刪除一個category,
getCategories()獲取intent全部的category.

Type:顯式指定Intent的數據類型(MIME)(多用途互聯網郵件擴展,Multipurpose Internet Mail Extensions)。好比,一個組件是能夠顯示圖片數據的而不能播放聲音文件。不少狀況下,data類型可在URI中找到,好比content:開頭的URI,代表數據由設備上的content provider提供。可是經過設置這個屬性,能夠強制採用顯式指定的類型而再也不進行推導。


MIME類型有2種形式

1.1  單個記錄的格式: vnd.android.cursor.item/vnd.yourcompanyname.contenttype,如:content://com.example.transportationprovider/trains/122(一條列車信息的uri)的MIME類型是vnd.android.cursor.item/vnd.example.rail

1.2 多個記錄的格式:vnd.android.cursor.dir/vnd.yourcompanyname.contenttype,如:content://com.example.transportationprovider/trains (全部列車信息)的MIME類型是vnd.android.cursor.dir/vnd.example.rail

component:指定Intent的目標組件的類名稱。一般 Android會根據Intent 中包含的其它屬性的信息,好比action、data/type、category進行查找,最終找到一個與之匹配的目標組件。可是,若是 component這個屬性有指定的話,將直接使用它指定的組件,而再也不執行上述查找過程。指定了這個屬性之後,Intent的其它全部屬性都是可選的。例如:

Intent it = new Intent(Activity.Main.this, Activity2.class); 

startActivity(it);


extras:附加信息,例如ACTION_TIMEZONE_CHANGED的intent有一個"time-zone"附加信息來指明新的時區,而ACTION_HEADSET_PLUG有一個「state」附加信息來指示耳機是被插入仍是被拔出。intent對象有一系列put...()和set...()方法來設定和獲取附加信息。 這些方法和Bundle對象很像。事實上附加信息可使用putExtras()和getExtras()做爲Bundle來讀和寫。例如:

用Bundle傳遞數據:

Intent it = new Intent(Activity.Main.this, Activity2.class);

Bundle bundle=new Bundle(); 

bundle.putString("name", "This is from MainActivity!"); 

it.putExtras(bundle); 

startActivity(it);

 //得到數據

Bundle bundle=getIntent().getExtras(); 

String name=bundle.getString("name");


intent的解析:

在應用中,咱們能夠以兩種形式來使用Intent:

1.1 顯式Intent:指定了component屬性的Intent(調用setComponent(ComponentName)或者setClass(Context, Class)來指定)。經過指定具體的組件類,通知應用啓動對應的組件。

2.2 隱式Intent:沒有指定comonent屬性的Intent。這些Intent須要包含足夠的信息,這樣系統才能根據這些信息,在在全部的可用組件中,肯定知足此Intent的組件。
對於直接Intent,Android不須要去作解析,由於目標組件已經很明確,Android須要解析的是那些間接Intent,經過解析將 Intent映射給能夠處理此Intent的Activity、Service或Broadcast Receiver。

Intent解析機制

Intent解析機制主要是經過查找已註冊在AndroidManifest.xml中的全部<intent-filter>及其中定義的Intent,經過PackageManager(注:PackageManager可以獲得當前設備上所安裝的application package的信息)來查找能處理這個Intent的component。在這個解析過程當中,Android是經過Intent的action、type、category這三個屬性來進行判斷的,判斷方法以下:1.1  若是Intent指明定了action,則目標組件的IntentFilter的action列表中就必須包含有這個action,不然不能匹配;1.2  若是Intent沒有提供type,系統將從data中獲得數據類型。和action同樣,目標組件的數據類型列表中必須包含Intent的數據類型,不然不能匹配。1.3  若是Intent中的數據不是content:類型的URI,並且Intent也沒有明確指定type,將根據Intent中數據的scheme(好比 http:或者mailto:)進行匹配。同上,Intent 的scheme必須出如今目標組件的scheme列表中。1.4 若是Intent指定了一個或多個category,這些類別必須所有出如今組建的類別列表中。好比Intent中包含了兩個類別:LAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY,解析獲得的目標組件必須至少包含這兩個類別。

相關文章
相關標籤/搜索