在Android的聯(lián)機(jī)文檔中,有對(duì)Activity的簡(jiǎn)單介紹,現(xiàn)在通過(guò)編寫代碼對(duì)Activity的啟動(dòng)模式做一個(gè)深入的理解。
在配置文件AndroidManifest.xml中,activity元素的android:launchMode屬性用來(lái)配置對(duì)應(yīng)Activity的啟動(dòng)模式,目前有以下四種啟動(dòng)模式:
1.standard
2.singleTop
3.singleTask
4.singleInstance
如果不對(duì)Activity設(shè)置啟動(dòng)模式,默認(rèn)就是standard模式
一、standard
請(qǐng)看以下代碼,實(shí)現(xiàn)了一個(gè)Activity :
public class A_Activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView=new TextView(this);
textView.setText(this+"");//這里用于打印當(dāng)前Activity的hashcode,可以此判斷Activity實(shí)例是不是同一個(gè)對(duì)象
Button button=new Button(this);
button.setText("Go next activity");
button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent();
intent.setClass(A_Activity.this, A_Activity.class);//說(shuō)明發(fā)出Intent與啟動(dòng)的Activity都是A_Activity的實(shí)例
startActivity(intent);
}
});
LinearLayout layout=new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(textView);
layout.addView(button);
setContentView(layout);
}
}
運(yùn)行之,請(qǐng)看下圖:
點(diǎn)擊button后,注意看第一行的textView
由此可知,生成了新的A_Activity對(duì)象,這時(shí)我們按回退鍵,就會(huì)依次回到之前的Activity。點(diǎn)擊button的過(guò)程就是壓棧的過(guò)程,在standard模式下,就會(huì)不斷生成新的Activity對(duì)象
二、singleTop
singleTop和standard模式都會(huì)將intent發(fā)送給新的Activity實(shí)例,不同的是,如果創(chuàng)建Intent的時(shí)候棧頂有要?jiǎng)?chuàng)建的singleTop模式下的Activity實(shí)例,則將Intent發(fā)送給該實(shí)例,不會(huì)再創(chuàng)建Activity的新實(shí)例。
還是使用之前的代碼,只是設(shè)置A_Activity的啟動(dòng)模式為singleTop:android:launchMode="singleTop",運(yùn)行之,請(qǐng)看下圖:
這個(gè)時(shí)候我們無(wú)論點(diǎn)擊多少次button,textView都顯示同一個(gè)Activity實(shí)例,按回退鍵時(shí)會(huì)直接退出程序,表明在singleTop模式下,如果在棧頂存在Intent中那個(gè)目標(biāo)Activity的實(shí)例,就不會(huì)創(chuàng)建新的實(shí)例,而直接使用棧頂?shù)膶?duì)象,對(duì)于資源有限的移動(dòng)設(shè)備來(lái)說(shuō),也是有實(shí)際意義的。
如果是在不同Activity之間跳轉(zhuǎn),就會(huì)跟standard模式的情形一樣,請(qǐng)看下面代碼:
public class A_Activity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView=new TextView(this);
textView.setText(this+"");
Button button=new Button(this);
button.setText("Go B_Activity");
button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent();
intent.setClass(A_Activity.this, B_Activity.class);//從A跳轉(zhuǎn)到B
startActivity(intent);
}
});
LinearLayout layout=new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(textView);
layout.addView(button);
setContentView(layout);
}
}
public class B_Activity extends Activity {
/**<li>Description: </li>
*
* @param savedInstanceState
* @see android.app.Activity#onCreate(android.os.Bundle)
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
TextView textView=new TextView(this);
textView.setText(this+"");
Button button=new Button(this);
button.setText("Go A_Activity");
button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent();
intent.setClass(B_Activity.this, A_Activity.class);//從B跳轉(zhuǎn)到A
startActivity(intent);
}
});
LinearLayout layout=new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.addView(textView);
layout.addView(button);
setContentView(layout);
}
}
運(yùn)行后,如下圖:
點(diǎn)擊button后:
再點(diǎn)擊button后:
這樣每次都會(huì)創(chuàng)建目標(biāo)Activity的新實(shí)例,因?yàn)樵谔D(zhuǎn)時(shí),處于棧頂?shù)膶?duì)象不是目標(biāo)Activity的實(shí)例
三、singleTask
singleTask模式只能創(chuàng)建一個(gè)實(shí)例,當(dāng)發(fā)送一個(gè)Intent,目標(biāo)Activity為singleTask模式時(shí),系統(tǒng)會(huì)檢查棧里面是否已經(jīng)有該Activity的實(shí)例,如果有就直接將Intent發(fā)送給它,還是使用(二)中的代碼,將A_Activity啟動(dòng)模式設(shè)置為singleTask,B_Activity啟動(dòng)模式設(shè)置為standard,啟動(dòng)后如下圖:
點(diǎn)擊button后:
繼續(xù)點(diǎn)擊button:
由此可知,singleTask模式的A_Activity在棧中只有一個(gè)實(shí)例,可以被重復(fù)使用
并且,如果收到Intent生成一個(gè)新實(shí)例,那么用戶可以通過(guò)回退鍵回到上一個(gè)狀態(tài),如果是已經(jīng)存在的一個(gè)activity來(lái)處理這個(gè)Intent的話,就無(wú)法通過(guò)回退鍵回到上一個(gè)狀態(tài)(對(duì)singleInstance同樣適用) ,比如剛才最后一步如果再按回退鍵,就會(huì)直接退出程序,而不會(huì)回到上一步的狀態(tài)。
四、singleInstance
這個(gè)模式下的Activity在一個(gè)單獨(dú)的task棧中,這個(gè)棧也只能包含一個(gè)Activity的實(shí)例,將上面代碼稍微改動(dòng)一下,顯示taskId:
A_Activity 中:textView.setText(this.getTaskId()+"");
B_Activity 中:textView.setText(this.getTaskId()+"");
另外將B_Activity 設(shè)置為singleInstance模式,A_Activity 設(shè)置為standard模式,啟動(dòng)后:
點(diǎn)擊button后:
表明啟動(dòng)了新的task
總結(jié)四個(gè)模式的不同:
1、Intent的目標(biāo)Activity由哪個(gè)task持有
standard與singleTop的Activity所在task,與收到的Intent的發(fā)送者所在task相同,除非Intent包括參數(shù)FLAG_ACTIVITY_NEW_TASK,該參數(shù)會(huì)啟動(dòng)Activity到新的task中;singleTask和singleInstance總是把Activity作為一個(gè)task的根元素,它們不會(huì)被啟動(dòng)到其他task里
2、是否允許Activity的多個(gè)實(shí)例
standard與singleTop可以被實(shí)例化多次,可以存在不同task中,并且一個(gè)task可以包括同一activity的多個(gè)實(shí)例
singleTask與singleInstance則在同一個(gè)task中只能允許Activity的一個(gè)實(shí)例,并且是task的根元素
3、在同一個(gè)task棧中,是否允許其他Activity的實(shí)例存在
singleInstance單獨(dú)在一個(gè)task中,其他啟動(dòng)模式允許不同Activity的實(shí)例存在
4、是否每次生成新實(shí)例接收Intent
standard每次啟動(dòng)都會(huì)生成新實(shí)例
singleTop的activity如果在task的棧頂?shù)脑挘瑒t不生成新的activity實(shí)例,直接使用該實(shí)例,否則,就要生成新的實(shí)例
singleInstance在所在棧中是唯一的activity,它每次都會(huì)被重用
singleTask如果task棧中有該模式的Activity,就不生成新的activity實(shí)例,直接使用該實(shí)例,否則,就要生成新的實(shí)例
轉(zhuǎn)載:http://blog.csdn.net/leiswpu/article/details/6248528