2016.05.08
在Android實(shí)際項(xiàng)目開發(fā)中奔垦,會(huì)根據(jù)特定的需求為Activity指定恰當(dāng)?shù)膯?dòng)模式雌团。Activity的啟動(dòng)模式有四種棍厂,分別是standard棕孙、singleTop、singleTask脖律、singleInstance谢肾。可以在AndroidManifest.xml中<activity>標(biāo)簽下添加android:launchMode屬性來指定啟動(dòng)模式小泉。下面分別看一下這幾個(gè)啟動(dòng)模式芦疏。
1.standard
standard是Activity默認(rèn)的啟動(dòng)模式,在沒有人為指定的情況下微姊,所有的Activity都會(huì)自動(dòng)的使用這種啟動(dòng)模式酸茴。看代碼兢交,在點(diǎn)擊事件中啟動(dòng)MainActivity本身薪捍。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("MainActivity", this.toString());
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, MainActivity.class));
}
});
}
在onCreate()中打印當(dāng)前Activity的實(shí)例,并且啟動(dòng)MainActivity自身魁淳。運(yùn)行程序飘诗,按兩次Button与倡,看到LogCat打印日志為:
D/MainActivity: com.mwb.acticitylaunchmodetest.MainActivity@13519f86
D/MainActivity: com.mwb.acticitylaunchmodetest.MainActivity@f301d72
D/MainActivity: com.mwb.acticitylaunchmodetest.MainActivity@cc2bc07
可以看出界逛,每次點(diǎn)擊按鈕都會(huì)創(chuàng)建一個(gè)MainActivity的實(shí)例。此時(shí)返回棧中存在三個(gè)MainActivity的實(shí)例纺座。
2.singleTop
在這種模式下啟動(dòng)Activity息拜,如果在返回棧的棧頂已經(jīng)是該Activity,則不會(huì)創(chuàng)建新的Activity實(shí)例净响,會(huì)直接使用當(dāng)前的實(shí)例少欺。在上面例子中修改MainActivity的啟動(dòng)模式為singleTop,重新運(yùn)行程序馋贤,點(diǎn)擊按鈕赞别,LogCat打印日志為:
D/MainActivity: com.mwb.acticitylaunchmodetest.MainActivity@13519f86
因?yàn)楫?dāng)前的MainActivity已經(jīng)處于返回棧的棧頂,所以不管點(diǎn)擊多少次按鈕都不會(huì)打印新的日志配乓。
但是當(dāng)MainActivity并未在棧頂時(shí)仿滔,這時(shí)再點(diǎn)擊按鈕惠毁,還是會(huì)創(chuàng)建MainActivity的新實(shí)例。修改代碼崎页,測(cè)試一下鞠绰。
MainActivity.class修改為:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("MainActivity", this.toString());
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
});
}
創(chuàng)建SecondActivity.class:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.d("SecondActivity", this.toString());
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(SecondActivity.this, MainActivity.class));
}
});
}
運(yùn)行程序,分別點(diǎn)擊MainActivity和SecondActivity的按鈕飒焦,查看打印日志蜈膨。
D/MainActivity: com.mwb.acticitylaunchmodetest.MainActivity@13519f86
D/SecondActivity: com.mwb.acticitylaunchmodetest.SecondActivity@18a175c3
D/MainActivity: com.mwb.acticitylaunchmodetest.MainActivity@389e6134
可以看到創(chuàng)建了兩個(gè)不同的MainActivity實(shí)例,這是因?yàn)樵赟econdActivity中點(diǎn)擊按鈕時(shí)牺荠,此時(shí)棧頂Activity為SecondActivity翁巍,所以點(diǎn)擊SecondActivity的按鈕會(huì)創(chuàng)建一個(gè)新的MainActivity實(shí)例。
3.singleTask
當(dāng)Activity處于這種模式時(shí)休雌,每次啟動(dòng)Activity曙咽,系統(tǒng)會(huì)先在返回棧中檢查是否存在該Activity的實(shí)例,如果存在挑辆,會(huì)把在這個(gè)Activity之上的所有Activity出棧例朱,如果沒有就會(huì)創(chuàng)建一個(gè)新的實(shí)例。繼續(xù)修改上面例子的代碼鱼蝉。把MainActivity的啟動(dòng)模式設(shè)置為singleTask洒嗤,SecondACtivity的啟動(dòng)模式為默認(rèn)。
在MainActivity.class中增加:
@Override
protected void onRestart() {
super.onRestart();
Log.d("MainActivity", "onRestart()");
}
在SecondActivity.class中增加:
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("SecondActivity", "onDestroy()");
}
運(yùn)行程序魁亦,查看打印的日志渔隶。
D/MainActivity: com.mwb.acticitylaunchmodetest.MainActivity@13519f86
D/SecondActivity: com.mwb.acticitylaunchmodetest.SecondActivity@18a175c3
D/MainActivity: onRestart()
D/SecondActivity: onDestroy()
在SecondActivity中啟動(dòng)MainActivity時(shí),發(fā)現(xiàn)返回棧中已經(jīng)存在MainActivity的實(shí)例洁奈,并且在SecondActivity的下面间唉,所以SecondActivity從返回棧中出棧,MainActivity重新回到棧頂利术,所以MainActivity的onRestart()方法和SecondActivity的onDestory()方法執(zhí)行呈野。
4.singleInstance
在這種模式下會(huì)啟用一個(gè)新的返回棧來管理這個(gè)Activity。
繼續(xù)修改代碼印叁,把MainActivity的啟動(dòng)模式設(shè)置為默認(rèn)被冒,把SecondActivity啟動(dòng)模式設(shè)置為singleInstance,新建ThirdActivity.class啟動(dòng)模式也是默認(rèn)轮蜕。
修改MainActivity.class昨悼,打印此時(shí)的返回棧id,并且在點(diǎn)擊事件中啟動(dòng)SecondActivity.class
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("MainActivity", "Task id = " + getTaskId());
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, SecondActivity.class));
}
});
}
修改SecondActivity.class跃洛,打印此時(shí)返回棧id率触,并且在點(diǎn)擊事件中啟動(dòng)ThirdActivity.class
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Log.d("SecondActivity", "Task id = " + getTaskId());
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(SecondActivity.this, ThirdActivity.class));
}
});
}
新建ThirdActivity.class,也在onCreate()方法中打印此時(shí)的返回棧id汇竭。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third);
Log.d("ThirdActivity", "Task id = " + getTaskId());
}
運(yùn)行程序葱蝗,分別啟動(dòng)MainActivity痊剖,SecondActivity,ThirdActivity垒玲,查看打印日志
D/MainActivity: Task id = 45
D/SecondActivity: Task id = 46
D/ThirdActivity: Task id = 45
會(huì)發(fā)現(xiàn)當(dāng)啟動(dòng)SecondActivity時(shí)陆馁,返回棧id變了,就是因?yàn)镾econdActivity的啟動(dòng)模式為singleInstance合愈,這也就驗(yàn)證了我們前面說的叮贩,在singleInstance模式下會(huì)啟用一個(gè)新的返回棧來管理這個(gè)Activity。