如果返回路徑是唯一的情況
例如:注冊頁取消回到登錄頁新建Register.java
public class RegisterActivity extends SHNetworkActivity {
protected void onCreate(Bundle savedInstanceState){? ? ? ??
super.onCreate(savedInstanceState);? ? ? ?
?setContentView(R.layout.mobile_user_register);}
private class ViewHolder { private Button OkBtn, CancelBtn;}
private void initContent(){
mViewHolder = new ViewHolder();?
mViewHolder.CancelBtn = (Button) findViewById(R.id.cancel_btn);}
?mViewHolder.CancelBtn.setOnClickListener(new View.OnClickListener() {? ? ?
? ? @Override? ? ? ? ?
?? public void onClick(View v) {? ? ? ? ? ?
? ?Intent it = new Intent(RegisterActivity.this, LoginActivity.class);? ? ? ? ? ? ? ??
? startActivity(it);? ? ? ? ? ? ? ?
?finish();}}
如果返回上一步有多種情況的話另外就要講到啟動模式
singleInstancesingleInstance模式應(yīng)該算是四種啟動模式中最特殊也最復(fù)雜的一個(gè)了退疫,你也需要多花點(diǎn)功夫來理解這個(gè)模式。不同于以上三種啟動模式鸽素,指定為 singleInstance模式的活動會啟用一個(gè)新的返回棧來管理這個(gè)活動(其實(shí)如果 singleTask模式指定了不同的 taskAffinity蹄咖,也會啟動一個(gè)新的返回棧)。那么這樣做有什么意義呢付鹿?想象以下場景澜汤,假設(shè)我們的程序中有一個(gè)活動是允許其他程序調(diào)用的,如果我們想實(shí)現(xiàn)其他程序和我們的程序可以共享這個(gè)活動的實(shí)例舵匾,應(yīng)該如何實(shí)現(xiàn)呢俊抵?使用前面三種啟動模式肯定是做不到的,因?yàn)槊總€(gè)應(yīng)用程序都會有自己的返回棧坐梯,同一個(gè)活動在不同的返回棧中入棧時(shí)必然是創(chuàng)建了新的實(shí)例徽诲。而使用singleInstance模式就可以解決這個(gè)問題,在這種模式下會有一個(gè)單獨(dú)的返回棧來管理這個(gè)活動,不管是哪個(gè)應(yīng)用程序來訪問這個(gè)活動谎替,都共用的同一個(gè)返回棧偷溺,也就解決了共享活動實(shí)例的問題。為了幫助你可以更好地理解這種啟動模式钱贯,我們還是來實(shí)踐一下挫掏。修改 AndroidManifest.xml 中 SecondActivity 的啟動模式:
我們先將 SecondActivity 的啟動模式指定為 singleInstance,然后修改 FirstActivity 中onCreate()方法的代碼:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("FirstActivity", "Task id is " + getTaskId());
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.first_layout);Button button1 = (Button) findViewById(R.id.button_1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
}});}
在 onCreate()方法中打印了當(dāng)前返回棧的 id秩命。然后修改 SecondActivity 中 onCreate()方法的代碼:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("SecondActivity", "Task id is " + getTaskId());
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.second_layout);Button button2 = (Button) findViewById(R.id.button_2);
button2.setOnClickListener(new OnClickListener() {
@Overridepublic void onClick(View v) {
Intent intent = new Intent(SecondActivity.this,ThirdActivity.class);startActivity(intent);}});}同樣在 onCreate()方法中打印了當(dāng)前返回棧的 id尉共,然后又修改了按鈕點(diǎn)擊事件的代碼,用于啟動 ThirdActivity弃锐。最后修改 ThirdActivity 中 onCreate()方法的代碼:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("ThirdActivity", "Task id is " + getTaskId());
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.third_layout);}
仍然是在 onCreate()方法中打印了當(dāng)前返回棧的 id“烙眩現(xiàn)在重新運(yùn)行程序,在 FirstActivity界 面 點(diǎn) 擊 按 鈕 進(jìn)入 到 SecondActivity 霹菊, 然 后 在 SecondActivity 界 面 點(diǎn) 擊 按 鈕 進(jìn)入 到ThirdActivity剧蚣。查看 LogCat 中的打印信息,如圖 2.37所示旋廷∪校可以看到,SecondActivity 的 Task id 不同于 FirstActivity 和 ThirdActivity柳洋,這說明SecondActivity 確實(shí)是存放在一個(gè)單獨(dú)的返回棧里的待诅,而且這個(gè)棧中只有 SecondActivity 這一個(gè)活動。然后我們按下 Back鍵進(jìn)行返回熊镣,你會發(fā)現(xiàn) ThirdActivity竟然直接返回到了 FirstActivity卑雁,再按下 Back 鍵又會返回到 SecondActivity,再按下 Back 鍵才會退出程序绪囱,這是為什么呢测蹲?其實(shí)原理很簡單,由于 FirstActivity 和 ThirdActivity 是存放在同一個(gè)返回棧里的鬼吵,當(dāng)在ThirdActivity 的界面按下 Back 鍵扣甲,ThirdActivity 會從返回棧中出棧,那么 FirstActivity 就成為了棧頂活動顯示在界面上齿椅,因此也就出現(xiàn)了從 ThirdActivity 直接返回到 FirstActivity 的情況琉挖。然后在 FirstActivity 界面再次按下 Back 鍵,這時(shí)當(dāng)前的返回棧已經(jīng)空了涣脚,于是就顯示了另一個(gè)返回棧的棧頂活動示辈,即 SecondActivity。最后再次按下 Back 鍵遣蚀,這時(shí)所有返回棧都已經(jīng)空了矾麻,也就自然退出了程序纱耻。
》》》》》》》》》》》》》》》》》》》》》》》》》》》
如果該活動并沒有處于棧頂?shù)奈恢茫€是可能會創(chuàng)建多個(gè)活動實(shí)例的险耀。那么有沒有什么辦法可以讓某個(gè)活動在整個(gè)應(yīng)用程序的上下文中只存在一個(gè)實(shí)例呢弄喘?這就要借助singleTask模式來實(shí)現(xiàn)了。當(dāng)活動的啟動模式指定為 singleTask甩牺,每次啟動該活動時(shí)系統(tǒng)首先會在返回棧中檢查是否存在該活動的實(shí)例蘑志,如果發(fā)現(xiàn)已經(jīng)存在則直接使用該實(shí)例,并把在這個(gè)活動之上的所有活動統(tǒng)統(tǒng)出棧柴灯,如果沒有發(fā)現(xiàn)就會創(chuàng)建一個(gè)新的活動實(shí)例。我們還是通過代碼來更加直觀地理解一下费尽。修改 AndroidManifest.xml 中 FirstActivity 的啟動模式:然后在 FirstActivity 中添加 onRestart()方法赠群,并打印日志:
@Overrideprotected void onRestart() {super.onRestart();Log.d("FirstActivity", "onRestart");}最后在 SecondActivity 中添加 onDestroy()方法,并打印日志:@Overrideprotected void onDestroy() {super.onDestroy();Log.d("SecondActivity", "onDestroy");}現(xiàn)在重新運(yùn)行程序旱幼,在 FirstActivity 界面點(diǎn)擊按鈕進(jìn)入到 SecondActivity查描,然后在SecondActivity 界面點(diǎn)擊按鈕,又會重新進(jìn)入到 FirstActivity柏卤。查看 LogCat 中的打印信息冬三,如圖 2.35 所示。其實(shí)從打印信息中就可以明顯看出了缘缚,在 SecondActivity 中啟動 FirstActivity 時(shí)勾笆,會發(fā)現(xiàn)返回棧中已經(jīng)存在一個(gè) FirstActivity 的實(shí)例,并且是在 SecondActivity 的下面桥滨,于是SecondActivity 會從返回棧中出棧窝爪,而 FirstActivity 重新成為了棧頂活動,因此 FirstActivity的 onRestart()方法和 SecondActivity 的 onDestroy()方法會得到執(zhí)行∑朊剑現(xiàn)在返回棧中應(yīng)該只剩下一個(gè) FirstActivity 的實(shí)例了蒲每,按一下 Back 鍵就可以退出程序。