Intent
Android中提供了Intent機(jī)制來協(xié)商引用之間的交互和通訊,或者采用更加準(zhǔn)確的是說法是,Intent不僅可以用與應(yīng)用程序內(nèi)部的activity,service和broadcasst receiver之間的交互。Intent這個英語單詞的本意是目的、意圖。
Intent是一種運(yùn)行時綁定(running binging)機(jī)制,它能在程序運(yùn)行的過程中連接兩個不同的組件。通過Intent,你的程序可以向Android表達(dá)某種請求或者醫(yī)院,Android會更具醫(yī)院的內(nèi)容選擇適當(dāng)?shù)慕M件來響應(yīng)。
對于向這三種組件發(fā)送intent有不同的機(jī)制:
使用Context.startActivity()或Activity.startActivityForResult(),傳入一個intent來啟動一個Activity。
使用Activity.seetResult(),傳入一個intent來從activty中返回結(jié)果。
將intent對象傳給Context.startService()來啟動一個service或者傳消息給一個運(yùn)行的service。
將intent對象傳遞給Context.bindService()綁定一個service。
將對象傳給Context.sendService()來綁定一個service。
將intent對象傳給Context.sendBroadcast(),Context.sendOrderedBroadcast(),或者Context.sendStickyBroadCast()等廣播方法,則他們被傳給broadcast receiver。
Intent由以下各個組成部分:
- component(組件):目的組件
- Action(動作):用來表現(xiàn)意圖的行動
- category(類別):用來表現(xiàn)動作的類別
- data(數(shù)據(jù)):表示與動作要操作的數(shù)據(jù)
- type(數(shù)據(jù)類型):對于data范例的描寫
- extras(擴(kuò)展信息):擴(kuò)展信息
- Flags(標(biāo)志位):期望這個意圖的運(yùn)行模式
Intent分為直接Intent和間接Intent
/**
* 直接查找法,通過組件名稱查找intent
* @param v
*/
public void compentClick(View v){
//方法一:
// Intent intent = new Intent();
// //組件名稱
// ComponentName componentName = new ComponentName(this,MainActivity2.class);
//
// //通過intent設(shè)置組件名稱直接跳轉(zhuǎn)
// intent.setComponent(componentName);
//方法二:
Intent intent = new Intent(this,MainActivity2.class);
//啟動Activity
startActivity(intent);
}
}
Intent的相關(guān)屬性
Action
用來表現(xiàn)意圖的行動
在Intent中,Action就是描述看、寫、做等動作的,當(dāng)你指定了一個Action,執(zhí)行者就會依照這個動作的指示,接受相關(guān)輸入,表現(xiàn)對應(yīng)行為,產(chǎn)生符合的輸出。在Intent類中,定義了一批量的動作,比如,Action_VIEW,ACTION_PICK等,基本涵蓋了常用動作。
Action是用戶定義的字符串,用于描述一個Android應(yīng)用程序組件,一個Intent Filter可以包含多個Action,AndroidManifest.xml的Activity定義時可以在其<intent-filter>結(jié)點(diǎn)指定一個Action列表,用于標(biāo)識Activity所能接受的“動作”
被匹配的Activity的Manifest文件指定自己的Action
<!--默認(rèn)Action沒有配置category時,必須寫 <category android:name="android.intent.category.DEFAULT"></category> -->
<activity
android:name=".MainActivity3"
android:label="@string/title_activity_main3"
android:theme="@style/AppTheme.NoActionBar" >
<intent-filter>
<action android:name="com.example.action.MY_ACTION"/>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
點(diǎn)擊跳到一個Activity
//間接查找,通過action動作
public void actionClick(View v){
Intent intent = new Intent();
//對應(yīng)的Action的名稱應(yīng)該相同,一般是包名后.action.大寫名字 intent.setAction("com.example.action.MY_ACTION");
startActivity(intent);
}
- 當(dāng)兩個Activity的Action相同時,會同時跳出兩個Activity,讓用戶自己選擇。
- 設(shè)置優(yōu)先級時,有個Activity的優(yōu)先級必須為負(fù)數(shù)
- 一個Activity可以有多個Action,只要有一個匹配就可以啟動。
Category
Manifest文件配置,必須有
category的默認(rèn)類別
<activity
android:name=".MainActivity3"
android:label="@string/title_activity_main3"
android:theme="@style/AppTheme.NoActionBar" >
<intent-filter>
<action android:name="com.example.action.MY_ACTION"/>
<category android:name="com.example.category.MY_CATEGORY"></category>
<category android:name="android.intent.category.DEFAULT"></category>
</intent-filter>
</activity>
Activity
//間接查找,通過category動作
public void actionClick(View v){
Intent intent = new Intent();
intent.setAction("com.example.action.MY_ACTION");
intent.addCategory("com.example.category.MY_CATEGORY");
startActivity(intent);
}
Data
Manifest
<activity
android:name=".MainActivity4"
android:label="@string/title_activity_main4"
android:theme="@style/AppTheme.NoActionBar" >
<intent-filter>
<action android:name="com.example.action.MY_ACTION"></action>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="http" android:host="www.baidu.com"></data>
</intent-filter>
</activity>
Activity
/**
* data實(shí)際上是一個URI,需要搭配Action使用
* @param v
*/
public void dataClick(View v){
Intent intent = new Intent();
intent.setAction("com.example.action.MY_ACTION");
Uri data = Uri.parse("http://www.baidu.com");
intent.setData(data);
startActivity(intent);
}/**
* data實(shí)際上是一個URI,需要搭配Action使用
* @param v
*/
public void dataClick(View v){
Intent intent = new Intent();
intent.setAction("com.example.action.MY_ACTION");
Uri data = Uri.parse("http://www.baidu.com");
intent.setData(data);
startActivity(intent);
}/**
* data實(shí)際上是一個URI,需要搭配Action使用
* @param v
*/
public void dataClick(View v){
Intent intent = new Intent();
intent.setAction("com.example.action.MY_ACTION");
Uri data = Uri.parse("http://www.baidu.com");
intent.setData(data);
startActivity(intent);
}
Type
如果Intent對象中既包含Uri又包含Type,那么,在<intent-filter>中也必須二者都包含才能通過測試
Type屬性則明確指定Data屬性的數(shù)據(jù)類型或MIME類型,但是通常來說,當(dāng)Intent不指定Data屬性時,Type屬性才能起作用,否則Android系統(tǒng)將會根據(jù)Data屬性值來分析數(shù)據(jù)的類型,所以無需指定Type屬性。
Type和Data
清單配置文件
<activity
android:name=".MainActivity4"
android:label="@string/title_activity_main4"
android:theme="@style/AppTheme.NoActionBar" >
<intent-filter>
<action android:name="com.example.action.MY_ACTION"></action>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="http" android:host="www.baidu.com" android:mimeType="text/html"></data>
</intent-filter>
</activity>
Activity
public void dataClick(View v){
Intent intent = new Intent();
intent.setAction("com.example.action.MY_ACTION");
Uri data = Uri.parse("http://www.baidu.com");
intent.setData(data);
//type用來表示數(shù)據(jù)的類型
//源碼中設(shè)置Data會把Type
//兩個都設(shè)置,用以下屬性
intent.setDataAndType(data,"text/html");
startActivity(intent);
}
extras擴(kuò)展信息
傳自定義的對象,序列化,參考Activity
Flags標(biāo)志位
一個程序啟動系統(tǒng)會為這個程序分配一個Task供使用,另外同一個task里面可以擁有不同應(yīng)用程序的Activity。一個程序能不能擁有多個Task?這就涉及到加載activty的四種模式:standard、singleTop、singleTask、singleInstance,可以在AndroidManifest.xml中activtiy標(biāo)簽屬性launchMode中設(shè)置該activity的加載模式。簡述一下四種模式的區(qū)別:
- standard模式:默認(rèn)的模式,以這中模式加載愛必定會構(gòu)造一個新的Activity實(shí)例,方到目標(biāo)的Task中的Activity棧頂,不管當(dāng)前棧頂是什么情況
2.singleTop模式:這種模式與standard模式類似,區(qū)別在于加載activity會多個判斷步驟。判斷需要加載的新的Activity與當(dāng)前task棧頂?shù)腁ctivity是不是同一個,相同的話就不再構(gòu)造新的activity,并調(diào)用這個Activity的new Instance()方,不相同就還會構(gòu)造新的activity放到棧頂
3.singleTask模式:這種模式下,會創(chuàng)建一個新的task來加載這個activity,并且這個Task值允許存在一個activity實(shí)例(以后可以加載其他activity的實(shí)例)
sinaleInstance模式:這種模式下,會創(chuàng)建一個新的task,并且這個Task中只能存在一個需要加載的Activity實(shí)例(以后可以加載其他activity)。
standard:
清單文件
<activity
android:name=".MainActivityA"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivityB"
android:label="@string/title_activity_main_activity_b"
android:theme="@style/AppTheme.NoActionBar"
android:launchMode="standard">
</activity>
</application>
AB兩個activity的布局文件
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="使用action屬性查找"
android:id="@+id/button_action"
android:onClick="actionClick"
android:layout_below="@+id/button_comp"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="使用data屬性查找組件"
android:id="@+id/button_data"
android:onClick="dataClick"
android:layout_below="@+id/button_action"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true" />
AB兩個Activity
public void startA(View v){
Intent intent = new Intent(this,MainActivityA.class);
startActivity(intent);
}
public void startB(View v){
Intent intent = new Intent(this,MainActivityB.class);
startActivity(intent);
}
Intent應(yīng)用
顯示網(wǎng)頁
Uri uri = Uri.parse("http://www.baidu.com");
Intent it = new Intent(Intent.ACTION_VIEW,uri);
startActivity(it);
撥打電話
打開打電話的界面:
Uri uri = Uri.parse("tel:xxxxxxx");
Intent it = new Intent(Intent.ACTION_DIAL,uri);
startActivity(it);
打電話:
Uri uri = Uri.parse("tel:xxxxxxx");
Intent it = new Intent(Intent.ACTION_CALL,uri);
startActivity(it);
//使用這個必須在配置文件中加入<uses-permission android:name="android.permission.CALL_PHONE"/>
調(diào)用發(fā)送短信的程序
Intent it = new Intent(Intent.ACTION_VIEW);
it.putExtra("sms_body","The SMS text");
it.setType("vnd.android-dir/mms-sms");
startActivity(it);
發(fā)送短信
Uri uri = Uri.parse("smsto:xxxxxxx");
Intent it = new Intent(Intent.ACTION_SENDTO,uri);
it.putExtra("sms_body","The SMS text");
startActivity(it);