Intent 意圖
Android 四大組件的紐帶乌妙,它的運行機制是(Run-time-binding)運行時綁定機制,它能在程序運行過程中連接兩個不同的組件灾搏。
Android的三個基本組件
Activity嫂沉、Service、Broadcast Receiver
都是通過Intent機制激活的阶女,不同類型的組件有不同的傳遞Intent方式颊糜。
Intent一旦發(fā)出,android都會準確找到相匹配的一個或多個Activity秃踩,Service或者BroadcastReceiver作響應衬鱼。所以,不同類型的Intent消息不會出現(xiàn)重疊憔杨,即Broadcast的Intent消息只會發(fā)送給BroadcastReceiver鸟赫,而決不會發(fā)送給Activity或者Service。由startActivity()傳遞的消息也只會發(fā)給Activity消别,由startService()傳遞的Intent只會發(fā)送給Service抛蚤。
Intent分類
名稱 | 說明 |
---|---|
顯式 | 通過指定具體的組件類,通知應用啟動對應的組件 |
隱式 | 沒有指定具體comonent屬性的Intent寻狂,設置了Action岁经、Data、Category蛇券,讓系統(tǒng)來篩選出合適的組件來進行調(diào)用(通過<Intent-filter>來篩選) |
Intent的構成
名稱 | 方法 | 作用 | 是否必選 |
---|---|---|---|
ComponentName | setComponent()\setClass()\setClassName() \Intent 構造函數(shù)設置組件名稱 | 描述要跳轉的組件名稱 | 否 |
action | setAction() \ Intent 構造函數(shù)為 Intent 指定操作 | 想要實施的動作 | 否 |
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 意味著缀壤,它應該在啟動器中作為頂級應用而存在 | 為實施的動作添加的額外信息,即Intent組件的種類信息纠亚,一個Intent對象可以有任意個category | 否 |
type | MIME類型 - 多用途互聯(lián)網(wǎng)郵件擴展塘慕,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 | 同步手機與數(shù)據(jù)服務器上的數(shù)據(jù) |
ACTION_BATTERY_LOW | broadcast receiver | 電池電量過低警告 |
ACTION_HEADSET_PLUG | broadcast receiver | 插拔耳機警告 |
ACTION_SCREEN_ON | broadcast receiver | 屏幕變亮警告 |
ACTION_TIMEZONE_CHANGED | broadcast receiver | 改變時區(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() | 設置Bundle數(shù)據(jù) |
getExtras() | 獲取Bundle數(shù)據(jù) |
.data和extras,即執(zhí)行動作要操作的數(shù)據(jù)和傳遞到目標的附加信息:
/**
* 打開指定網(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);
}
/**
* 進行關鍵字搜索
* @param view
*/
public void invokeWebSearch(View view) {
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, "android"); //關鍵字
startActivity(intent);
}
public void call(View view) {
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:12345678"));
startActivity(intent);
}
那么我們?nèi)绾沃滥繕耸欠窠邮苓@種前綴呢骗随?這就需要看一下目標中<data/>元素的匹配規(guī)則了蛤织。
在目標<data/>標簽中包含了以下幾種子元素,他們定義了url的匹配規(guī)則:
android:scheme 匹配url中的前綴鸿染,除了“http”瞳筏、“https”、“tel”...之外牡昆,我們可以定義自己的前綴
android:host 匹配url中的主機名部分姚炕,如“google.com”,如果定義為“*”則表示任意主機名
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>
這個時候如果只指定action就不夠了丢烘,我們需要為其設置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);
}
此時,url中的每個部分和TargetActivity配置信息中全部一致才能跳轉成功播瞳,否則就被系統(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組件很明確蚓炬,不需要解析就可以找到對應的組件松逊,做出響應。
2.對于隱示的Intent肯夏,組件不明確经宏,Android有相應地解析機制。
解析機制:
1.通過查找已注冊在AndroidManifest.xml的所有<intent-filter>及其中定義的intent
2.通過PackageManager來查找能夠處理這個Intent的component驯击,因為PackageManager能夠獲取設備上當前所安裝的application package信息烁兰,解析過程主要是通過intent中的action、type徊都、category三個屬性來判斷沪斟。
匹配規(guī)則:
1.如果指定action,則目標組件的IntentFilter需要含有這個action.
2.如果Intent沒有提供type暇矫,系統(tǒng)將從data中得到數(shù)據(jù)類型主之,類似action的匹配規(guī)則,目標組件必須包含Intent的數(shù)據(jù)類型袱耽,否則不匹配.
3.如果Intent中的數(shù)據(jù)不是content類型的Uri杀餐,而且Intent也沒有明確指定type干发,將根據(jù)Intent中數(shù)據(jù)的scheme(如 http:或者mailto:)進行匹配朱巨,同上,Intent的scheme必須出現(xiàn)在目標組件的scheme列表中.
4.如果Intent指定了一個或者多個category枉长,那么目標組件的類別列表需要包含全部所指定的類別(egLAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY)