Intent 意圖
Android 四大組件的紐帶,它的運(yùn)行機(jī)制是(Run-time-binding)運(yùn)行時(shí)綁定機(jī)制,它能在程序運(yùn)行過程中連接兩個不同的組件。
Android的三個基本組件
Activity、Service、Broadcast Receiver
都是通過Intent機(jī)制激活的,不同類型的組件有不同的傳遞Intent方式。
Intent一旦發(fā)出,android都會準(zhǔn)確找到相匹配的一個或多個Activity,Service或者BroadcastReceiver作響應(yīng)。所以,不同類型的Intent消息不會出現(xiàn)重疊,即Broadcast的Intent消息只會發(fā)送給BroadcastReceiver,而決不會發(fā)送給Activity或者Service。由startActivity()傳遞的消息也只會發(fā)給Activity,由startService()傳遞的Intent只會發(fā)送給Service。
Intent分類
| 名稱 | 說明 |
|---|---|
| 顯式 | 通過指定具體的組件類,通知應(yīng)用啟動對應(yīng)的組件 |
| 隱式 | 沒有指定具體comonent屬性的Intent,設(shè)置了Action、Data、Category,讓系統(tǒng)來篩選出合適的組件來進(jìn)行調(diào)用(通過<Intent-filter>來篩選) |
Intent的構(gòu)成
| 名稱 | 方法 | 作用 | 是否必選 |
|---|---|---|---|
| ComponentName | setComponent()\setClass()\setClassName() \Intent 構(gòu)造函數(shù)設(shè)置組件名稱 | 描述要跳轉(zhuǎn)的組件名稱 | 否 |
| action | setAction() \ Intent 構(gòu)造函數(shù)為 Intent 指定操作 | 想要實(shí)施的動作 | 否 |
| data | setData(uri data)\setDataAndType(Uri data, String type)\setDataAndTypeAndNormalize(Uri data, String type) \setDataAndNormalize(Uri data) | 引用待操作數(shù)據(jù)\該數(shù)據(jù) MIME 類型的 URI(Uri 對象) | 否 |
| category | addCategory(String category)\removeCategory(String category) 如:CATEGORY_LAUNCHER 意味著,它應(yīng)該在啟動器中作為頂級應(yīng)用而存在 | 為實(shí)施的動作添加的額外信息,即Intent組件的種類信息,一個Intent對象可以有任意個category | 否 |
| type | MIME類型 - 多用途互聯(lián)網(wǎng)郵件擴(kuò)展,Multipurpose Internet Mail Extensions MIME類型有兩種:單個記錄格式、多個記錄格式 | 顯示指定Intent的數(shù)據(jù)類型 | 否 |
| extras | it.putExtras(bundle) | 附件信息 | 否 |
Action:行為
| Action | 對象組件 | 名稱 |
|---|---|---|
| ACTION_CALL | Activity | 啟動撥打電話 |
| ACTION_MAIN | Activity | 作為Task中第一個Activity啟動 |
| ACTION_EDIT | Activity | 顯示用戶編輯的數(shù)據(jù) |
| ACTION_SYNC | Activity | 同步手機(jī)與數(shù)據(jù)服務(wù)器上的數(shù)據(jù) |
| ACTION_BATTERY_LOW | broadcast receiver | 電池電量過低警告 |
| ACTION_HEADSET_PLUG | broadcast receiver | 插拔耳機(jī)警告 |
| ACTION_SCREEN_ON | broadcast receiver | 屏幕變亮警告 |
| ACTION_TIMEZONE_CHANGED | broadcast receiver | 改變時(shí)區(qū)警告 |
android SDK-> reference中的Android.content.intent類,里面的constants中定義了所有的action。
<activity android:name=".TargetActivity">
<intent-filter>
<action android:name="com.scott.intent.action.TARGET"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
另一個Activity中y有
public void gotoTargetActivity(View view) {
Intent intent = new Intent("com.scott.intent.action.TARGET");
startActivity(intent);
}
Category 分類
| 方法 | 說明 |
|---|---|
| addCategory() | 方法為一個intent對象增加一個category |
| removeCategory | 刪除一個category |
| getCategories() | 獲取intent所有的category |
extras
| 方法 | 說明 |
|---|---|
| putExtras() | 設(shè)置Bundle數(shù)據(jù) |
| getExtras() | 獲取Bundle數(shù)據(jù) |
.data和extras,即執(zhí)行動作要操作的數(shù)據(jù)和傳遞到目標(biāo)的附加信息:
/**
* 打開指定網(wǎng)頁
* @param view
*/
public void invokeWebBrowser(View view) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com.hk"));
startActivity(intent);
}
/**
* 進(jìn)行關(guān)鍵字搜索
* @param view
*/
public void invokeWebSearch(View view) {
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, "android"); //關(guān)鍵字
startActivity(intent);
}
public void call(View view) {
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:12345678"));
startActivity(intent);
}
那么我們?nèi)绾沃滥繕?biāo)是否接受這種前綴呢?這就需要看一下目標(biāo)中<data/>元素的匹配規(guī)則了。
在目標(biāo)<data/>標(biāo)簽中包含了以下幾種子元素,他們定義了url的匹配規(guī)則:
android:scheme 匹配url中的前綴,除了“http”、“https”、“tel”...之外,我們可以定義自己的前綴
android:host 匹配url中的主機(jī)名部分,如“google.com”,如果定義為“*”則表示任意主機(jī)名
android:port 匹配url中的端口
android:path 匹配url中的路徑
我們改動一下TargetActivity的聲明信息:
<activity android:name=".TargetActivity">
<intent-filter>
<action android:name="com.scott.intent.action.TARGET"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="scott" android:host="com.scott.intent.data" android:port="7788" android:path="/target"/>
</intent-filter>
</activity>
這個時(shí)候如果只指定action就不夠了,我們需要為其設(shè)置data值,如下:
public void gotoTargetActivity(View view) {
Intent intent = new Intent("com.scott.intent.action.TARGET");
intent.setData(Uri.parse("scott://com.scott.intent.data:7788/target"));
startActivity(intent);
}
此時(shí),url中的每個部分和TargetActivity配置信息中全部一致才能跳轉(zhuǎn)成功,否則就被系統(tǒng)拒絕。
組件
Context.sendBroadcast()、Context.sendOrderBroadcast()、Context.sendStickBroadcast()這三個方法可以發(fā)送Broadcast Intent。發(fā)送之后,所有已注冊的并且擁有與之相匹配IntentFilter的BroadcastReceiver就會被激活。
Intent 啟動組件的方法:
| 組件名稱 | 方法名稱 |
|---|---|
| Activity | startActvity( ) startActivity( ) |
| Service | startService( ) bindService( ) |
| Broadcasts | sendBroadcasts( ) sendOrderedBroadcasts( ) sendStickyBroadcasts( ) |
Intent 的解析
1.對于顯示的Intent組件很明確,不需要解析就可以找到對應(yīng)的組件,做出響應(yīng)。
2.對于隱示的Intent,組件不明確,Android有相應(yīng)地解析機(jī)制。
解析機(jī)制:
1.通過查找已注冊在AndroidManifest.xml的所有<intent-filter>及其中定義的intent
2.通過PackageManager來查找能夠處理這個Intent的component,因?yàn)镻ackageManager能夠獲取設(shè)備上當(dāng)前所安裝的application package信息,解析過程主要是通過intent中的action、type、category三個屬性來判斷。
匹配規(guī)則:
1.如果指定action,則目標(biāo)組件的IntentFilter需要含有這個action.
2.如果Intent沒有提供type,系統(tǒng)將從data中得到數(shù)據(jù)類型,類似action的匹配規(guī)則,目標(biāo)組件必須包含Intent的數(shù)據(jù)類型,否則不匹配.
3.如果Intent中的數(shù)據(jù)不是content類型的Uri,而且Intent也沒有明確指定type,將根據(jù)Intent中數(shù)據(jù)的scheme(如 http:或者mailto:)進(jìn)行匹配,同上,Intent的scheme必須出現(xiàn)在目標(biāo)組件的scheme列表中.
4.如果Intent指定了一個或者多個category,那么目標(biāo)組件的類別列表需要包含全部所指定的類別(egLAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY)