.Activity的本質
Activity是Android提供的四大組件之一,是進行Android開發必不可少的組件.Activity是一個界面的載體,可以把它與html頁面進行類比,html頁面由各種各樣的標簽組成,而Activity則可以由各種控件組成.然而Activity也並不是那么簡單.查看Activity類的源碼我們就可以看到,這個類大概有六千多行代碼,說明Android對Activity的處理是相當復雜的.不過我們平時進行開發的時候不需要了解到那么深入的地步,因為我們可以根據Activity中提供的方法快速的開發,Activity生命周期中涉及到七個回調方法.
.Activity的生命周期
Android官方文檔給出的Activity生命周期圖
當打開一個Activity的時候,會調用這個Activity的onCreate()方法,接着調用onStart()方法,然后調用onResume()方法.當onStart()方法執行之后,我們就可以看到這個Activity界面了.下面通過代碼對單個Activity生命周期做進一步的解釋.
MainActivity.java

package com.example.caobotao.activitylifecircle; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i("info","MainActivity onCreate()"); } @Override protected void onStart() { super.onStart(); Log.i("info","MainActivity onStart()"); } @Override protected void onResume() { super.onResume(); Log.i("info","MainActivity onResume()"); } @Override protected void onPause() { super.onPause(); Log.i("info", "MainActivity onPause()"); } @Override protected void onStop() { super.onStop(); Log.i("info", "MainActivity onStop()"); } @Override protected void onDestroy() { super.onDestroy(); Log.i("info","MainActivity onDestroy()"); } @Override protected void onRestart() { super.onRestart(); Log.i("info","MainActivity onRestart()"); } }
運行項目后,Logcat輸出:
11-24 20:00:49.160 20104-20104/com.example.caobotao.activitylifecircle I/info: MainActivity onCreate() 11-24 20:00:49.170 20104-20104/com.example.caobotao.activitylifecircle I/info: MainActivity onStart() 11-24 20:00:49.170 20104-20104/com.example.caobotao.activitylifecircle I/info: MainActivity onResume()
點擊返回鍵,Logcat輸出:
11-24 20:05:15.370 20104-20104/com.example.caobotao.activitylifecircle I/info: MainActivity onStop() 11-24 20:05:15.370 20104-20104/com.example.caobotao.activitylifecircle I/info: MainActivity onDestroy()
下面簡單講一下Activity生命周期中每個函數的作用:
onCreate() :
當Activity第一次被創建的時候調用此方法.一般在此方法中進行控件的聲明,添加事件等初始化工作.
onStart():
當Activity被顯示到屏幕上的時候調用此方法.
onResume():
當此Activity能夠被操作之前,也就是能夠獲得用戶的焦點之前調用此方法.
onRestart():
當Activity被停止后又被再次啟動之前調用此方法.接着將調用onStart()方法.
onPause():
當第一個Activity通過Intent啟動第二個Activity的時候,將調用第一個Activity的onPause()方法.然后調用第二個Activity的onCreate(),onStart(),onResume()方法,接着調用第一個Activity的onStop()方法.如果Activity重新獲得焦點,則將調用onResume()方法;如果此Activity進入用戶不可見狀態,那么將調用onStop()方法.
onStop():
當第一個Activity被第二個Activity完全覆蓋,或者被銷毀的時候回調用此方法.如果此Activity還會與用戶進行交互,將調用onRestart方法();如果此Activity將被銷毀,那么將調用onDestroy()方法.
onDestroy():
Activity被銷毀之前調用此方法.或者是調用finish()方法結束Activity的時候調用此方法.可以在此方法中進行收尾工作,比如釋放資源等.
(注意:重寫某個Activity的這些回調方法的時候需要首先在第一行調用基類Activity的相應的回調方法.比如super.onCreate(),super.onStart()等等.)
接下來了解一下多個Activity交互中的生命周期.在第一個Activity中添加一個按鈕,用於啟動第二個Activity.
AActivity.java

package com.example.caobotao.activitylifecircle; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; public class AActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i("info","AActivity onCreate()"); findViewById(R.id.btnStartBAty).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(AActivity.this,BActivity.class)); } }); } @Override protected void onStart() { super.onStart(); Log.i("info","AActivity onStart()"); } @Override protected void onResume() { super.onResume(); Log.i("info","AActivity onResume()"); } @Override protected void onPause() { super.onPause(); Log.i("info", "AActivity onPause()"); } @Override protected void onStop() { super.onStop(); Log.i("info", "AActivity onStop()"); } @Override protected void onDestroy() { super.onDestroy(); Log.i("info","AActivity onDestroy()"); } @Override protected void onRestart() { super.onRestart(); Log.i("info","AActivity onRestart()"); } }
BActivity.java

package com.example.caobotao.activitylifecircle; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; public class BActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_baty); Log.i("info","BActivity oncreate()"); } @Override protected void onStart() { super.onStart(); Log.i("info","BActivity onStart()"); } @Override protected void onResume() { super.onResume(); Log.i("info","BActivity onResume()"); } @Override protected void onStop() { super.onStop(); Log.i("info","BActivity onStop()"); } @Override protected void onDestroy() { super.onDestroy(); Log.i("info", "BActivity onDestroy()"); } @Override protected void onRestart() { super.onRestart(); Log.i("info","BActivity onRestart()"); } }
運行項目后,Logcat輸出:
11-26 21:14:38.960 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onCreate() 11-26 21:14:38.970 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onStart() 11-26 21:14:38.970 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onResume()
點擊按鈕打開BActivity后,Logcat輸出:
11-26 21:14:42.050 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onPause() 11-26 21:14:42.080 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity oncreate() 11-26 21:14:42.090 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity onstart() 11-26 21:14:42.090 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity onresume() 11-26 21:14:45.750 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onstop()
然后點擊BACK鍵,Logcat輸出:
11-26 21:20:38.650 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity onPause() 11-26 21:20:38.970 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onRestart() 11-26 21:20:38.970 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onStart() 11-26 21:20:38.970 6208-6208/com.example.caobotao.activitylifecircle I/info: AActivity onResume() 11-26 21:20:41.710 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity onStop() 11-26 21:20:41.710 6208-6208/com.example.caobotao.activitylifecircle I/info: BActivity onDestroy()
可以看出,當啟動第二個Activity時,總是先調用第一個Activity的onPause()方法,然后如果第二個Activity是第一次創建的話,則再調用第二個Activity的onCreate()方法,否則調用第二個Activity的onRestart()方法,接着調用onStart(),onResume()方法.
.Activity生命周期交互設計思想
到這里,大家可能會有些疑問,谷歌為什么要這樣設計呢?如:
1.當從第一個Activity啟動第二個Activity的時候,為什么先調用第一個Activity的onPause()方法,然后再調用第二個Activity的onCreate()等方法呢?
解釋:假如有這樣一個情況,你正在使用APP聽音樂,突然來了一個電話,那么當然需要先暫停音樂,然后進行電話的處理。所以這就是onPause()方法的作用:可以用來保存當前的各種信息.可以在這個APP的onPause()方法中實現暫停音樂的邏輯,然后再處理電話的業務處理.
2.當從第一個Activity啟動第二個Activity的時候,為什么第一個Activity的onStop()方法是調用完第二個Activity的系列方法后才調用呢,為什么不在第一個Activity的onPause()方法之后就調用呢?
解釋:這是谷歌對安全方面的一個考慮.假如先調用第一個Activity的onStop()方法,那么此時第一個Activity將不可見,如果接下來調用第二個Activity的一系列創建方法失敗了,那么就會導致這兩個Activity都沒顯示在屏幕上,就會出現黑屏等不友好界面.如果是調用完第二個Activity一系列創建方法后,再調用第一個Activity的onStop()方法,就會避免這種情況的發生.
.Activity生命周期的應用場景
講了這么多,大家可能會問,Activity生命周期到底實際中怎么使用.下面通過實例來做簡單的運用.在AActivity中進行音樂的播放,當點擊按鈕打開BActivity后,音樂需要暫停,然后點擊BACK鍵返回到AActivity后音樂繼續播放.這就需要在AActivity中的onPause()方法中進行音樂的暫停操作,以及暫停時音樂播放位置的記錄.在AActivity中的onResume()方法中實現重新返回前台時繼續音樂的播放.
AActivity.java

package com.example.caobotao.activitylifecircle; import android.app.Activity; import android.content.Intent; import android.media.MediaPlayer; import android.os.Bundle; import android.util.Log; import android.view.View; public class AActivity extends Activity { private MediaPlayer mediaPlayer; private int position; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mediaPlayer = MediaPlayer.create(this,R.raw.song); mediaPlayer.start(); Log.i("info","AActivity onCreate()"); findViewById(R.id.btnStartBAty).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(AActivity.this,BActivity.class)); } }); } @Override protected void onStart() { super.onStart(); Log.i("info","AActivity onStart()"); } @Override protected void onResume() { super.onResume(); //如果播放的位置不是0 if (position != 0){ mediaPlayer.seekTo(position);//獲取播放的位置 mediaPlayer.start();//開始播放 } Log.i("info","AActivity onResume()"); } @Override protected void onPause() { super.onPause(); //如果播放器正在播放 if (mediaPlayer.isPlaying()){ mediaPlayer.pause();//暫停播放 position = mediaPlayer.getCurrentPosition();//獲得暫停時播放的位置 } Log.i("info", "AActivity onPause()"); } @Override protected void onStop() { super.onStop(); Log.i("info", "AActivity onStop()"); } @Override protected void onDestroy() { super.onDestroy(); Log.i("info","AActivity onDestroy()"); } @Override protected void onRestart() { super.onRestart(); Log.i("info","AActivity onRestart()"); } }
BActivity.java

package com.example.caobotao.activitylifecircle; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; public class BActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_baty); Log.i("info","BActivity onCreate()"); } @Override protected void onStart() { super.onStart(); Log.i("info","BActivity onStart()"); } @Override protected void onResume() { super.onResume(); Log.i("info","BActivity onResume()"); } @Override protected void onPause() { super.onPause(); Log.i("info","BActivity onPause()"); } @Override protected void onStop() { super.onStop(); Log.i("info","BActivity onStop()"); } @Override protected void onDestroy() { super.onDestroy(); Log.i("info", "BActivity onDestroy()"); } @Override protected void onRestart() { super.onRestart(); Log.i("info","BActivity onRestart()"); } }
.其他應用程序中的Activity
我們可以通過ComponentName啟動其他應用程序中的Activity,比如啟動相機等.
用法:
Intent intent=new Intent(); intent.setComponent(new ComponentName(String packageName,String activityName )); startActivity(intent);
.啟動系統中常見的Activity
系統給我們提供了很多常用的Activity,可以用來打開瀏覽器,打開發短信界面,打開相冊界面,打開撥號界面等等.
打開瀏覽器網頁:
Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
打開相冊:
Intent intent = new Intent(); intent.setAction(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); startActivity(intent);
打開發送短信界面:
Intent intent = new Intent(); intent.setAction(Intent.ACTION_SEND); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT,"Hello World !"); startActivity(intent);
打開撥號界面:
Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse("tel:110")); startActivity(intent);
.Activity之間的數據交互
我們可以使用Intent對象進行數據的傳遞.Intent重載了很多putExtra()方法,囊括了JAVA八大基本類型及其數組類型等.
Activity1.java

package com.example.caobotao.activitylifecircle; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; /** * Created by caobotao on 15/11/29. */ public class Activity1 extends Activity { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity1); button = (Button) findViewById(R.id.startAnotherActivity); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Activity1.this,Activity2.class); intent.putExtra("name","zhangsan"); intent.putExtra("age",23); startActivity(intent); } }); } }
Activity2.java

package com.example.caobotao.activitylifecircle; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.TextView; /** * Created by caobotao on 15/11/29. */ public class Activity2 extends Activity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity2); textView = (TextView) findViewById(R.id.textView); Intent intent = getIntent(); if (intent != null){ String name = intent.getStringExtra("name"); int age = intent.getIntExtra("age",0);//設0為默認值 textView.setText("姓名: " + name + "\n年齡: " + age); } } }
Intent對象還有一個putExtras(Bundle bundle)方法,bundle的意思為一捆,就是把需要傳遞的數據打成一捆進行傳遞.下面利用Bundle實現上面的示例,效果一樣.
Activity1.java

package com.example.caobotao.activitylifecircle; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; /** * Created by caobotao on 15/11/29. */ public class Activity1 extends Activity { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity1); button = (Button) findViewById(R.id.startAnotherActivity); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Activity1.this,Activity2.class); Bundle bundle = new Bundle(); bundle.putString("name","zhangsan"); bundle.putInt("age",23); intent.putExtras(bundle); startActivity(intent); } }); } }
Activity2.java

package com.example.caobotao.activitylifecircle; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.TextView; /** * Created by caobotao on 15/11/29. */ public class Activity2 extends Activity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity2); textView = (TextView) findViewById(R.id.textView); Intent intent = getIntent(); if (intent != null){ String name = intent.getStringExtra("name"); int age = intent.getIntExtra("age",0);//設0為默認值 textView.setText("姓名: " + name + "\n年齡: " + age); } } }
在實際開發中,可能需要傳遞的數據比較多,不僅有姓名,年齡,可能還有性別,學校,愛好等等.根據面向對象的思想,我們應該想到把這些信息封裝成一個java實體類,以達到更好的復用性,耦合性等目的,然后使用Bundle對象的putSerializable()方法將此需要傳遞的對象傳遞出去,在另一個Activity中用Intent對象的getSerializableExtra()方法進行接收.
Person.java

package com.example.caobotao.activitylifecircle; import java.io.Serializable; /** * Created by caobotao on 15/11/29. */ public class Person implements Serializable { private String name; private int age; private String school; private String address; public Person(){} public Person(String name,int age,String school,String address){ this.name = name; this.age = age; this.school = school; this.address = address; } @Override public String toString() { return "姓名: " + name + "\n年齡: " + age + "\n學校: " + school + "\n地址: " + address; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } }
Activity1.java

package com.example.caobotao.activitylifecircle; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; /** * Created by caobotao on 15/11/29. */ public class Activity1 extends Activity { private Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity1); button = (Button) findViewById(R.id.startAnotherActivity); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Activity1.this,Activity2.class); Person person = new Person("zhangsan",23,"USST","ShangHai"); Bundle bundle = new Bundle(); bundle.putSerializable("person",person); intent.putExtras(bundle); startActivity(intent); } }); } }
Activity2.java

package com.example.caobotao.activitylifecircle; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.TextView; /** * Created by caobotao on 15/11/29. */ public class Activity2 extends Activity { private TextView textView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity2); textView = (TextView) findViewById(R.id.textView); Intent intent = getIntent(); if (intent != null) { Person person = (Person) intent.getSerializableExtra("person"); textView.setText(person.toString()); } } }
.Task與Back Stack(引自官方文檔)
task 是一系列被操作的 activity 的集合,用戶進行操作時將與這些 activity 進行交互。 這些 activity 按照啟動順序排隊存入一個棧(即“back stack”)。我們知道棧是一個后進先出的數據結構,在一個task中,每打開一個新的activity,就會將其壓入棧頂的位置;每次點擊Back鍵,棧頂的activity就會被移除.
大部分 task 都啟動自 Home 屏幕。當用戶觸摸 application launcher 中的圖標(或 Home 屏幕上的快捷圖標)時,應用程序的 task 就進入前台。 如果該應用不存在 task(最近沒有使用過此應用),則會新建一個 task,該應用的“main”activity 作為棧的根 activity 被打開。
當用戶返回到 home屏幕執行另一個 task 時,一個 task 被移動到后台執行,此時它的返回棧(back stack)也被保存在后台, 同時 android 為新 task 創建一個新的返回棧(back stack),當它被再次運行從而返回前台時,它的返回棧(back stack)被移到前台,並恢復其之前執行的activity,如下圖所示。 如果后台有太多運行 task ,系統將會殺死一些 task 釋放內存。
如果當前 activity 啟動了另一個 activity,則新的 activity 被壓入棧頂並獲得焦點。 前一個 activity 仍保存在棧中,但是被停止。activity 停止時,系統會保存用戶界面的當前狀態。 當用戶按下返回鍵,則當前 activity 將從棧頂彈出(被銷毀),前一個 activity 將被恢復(之前的用戶界面狀態被恢復)。 activity 在棧中的順序永遠不會改變,只會壓入和彈出——被當前 activity 啟動時壓入棧頂,用戶用返回鍵離開時彈出。 這樣,back stack 以“后進先出”的方式運行。下圖以時間線的方式展示了多個 activity 切換時對應當前時間點的 back stack 狀態。
圖: task 中的每個新 activity 都會相應在 back stack 中增加一項。當用戶按下返回鍵時,
當前 activity 被銷毀,前一個 activity 被恢復。
如果用戶不停地按下返回鍵,則棧中每個 activity 都會依次彈出,並顯示前一個 activity,直至用戶回到 Home 屏幕(或者任一啟動該 task 的 activity)。 當所有 activity 都從棧中彈出后, task 就此消失。
.Activity啟動模式(引自官方文檔)
在 manifest 文件中聲明 activity 時,你可以利用activity元素的launchMode屬性來設定 activity 與 task 的關系。
launchMode 屬性指明了 activity 啟動 task 的方式。 launchMode 屬性可設為四種啟動模式:
- standard(默認模式):
- 默認值。系統在啟動 activity 的 task 中創建一個新的 activity 實例,並把 intent 傳送路徑指向它。該 activity 可以被實例化多次,各個實例可以屬於不同的 task,一個 task 中也可以存在多個實例。
singleTop:
- 如果 activity 已經存在一個實例並位於當前 task 的棧頂,則系統會調用已有實例的onNewIntent()方法把 intent 傳遞給已有實例,而不是創建一個新的 activity 實例。activity 可以被實例化多次,各個實例可以屬於不同的 task,一個 task 中可以存在多個實例(但僅當 back stack 頂的 activity 實例不是該 activity 的)。
- 比如,假定 task 的 back stack 中包含了根 activity A 和 activities B、C、D(順序是 A-B-C-D;D 在棧頂)。
- 這時過來一個啟動 D 的 intent。如果 D 的啟動模式是默認的"standard",則會啟動一個新的實例,棧內容變為 A-B-C-D-D。
- 但是,如果 D 的啟動模式是"singleTop",則已有的 D 實例會通過onNewIntent():接收這個 intent,因為該實例位於棧頂——棧中內容仍然維持 A-B-C-D 不變。當然,如果 intent 是要啟動 B 的,則 B 的一個新實例還是會加入棧中,即使 B 的啟動模式是"singleTop"也是如此。
注意: 一個 activity 的新實例創建完畢后,用戶可以按回退鍵返回前一個 activity。 但是當 activity 已有實例正在處理剛到達的 intent 時,用戶無法用回退鍵回到 onNewIntent() 中 intent 到來之前的 activity 狀態。
- singleTask:
- 系統將創建一個新的 task,並把 activity 實例作為根放入其中。但是,如果 activity 已經在其它 task 中存在實例,則系統會通過調用其實例的onNewIntent() 方法把 intent 傳給已有實例,而不是再創建一個新實例。 此 activity 同一時刻只能存在一個實例。
注意: 雖然 activity 啟動了一個新的 task,但用戶仍然可以用回退鍵返回前一個 activity。
singleInstance:
- 除了系統不會把其它 activity 放入當前實例所在的 task 之外,其它均與"singleTask"相同。activity 總是它所在 task 的唯一成員;它所啟動的任何 activity 都會放入其它 task 中。
舉個例子,Android 的瀏覽器應用就把 web 瀏覽器 activity 聲明為總是在它自己獨立的 task 中打開——把 activity設為singleTask模式。 這意味着,如果你的應用提交 intent 來打開 Android 的瀏覽器,則其 activity 不會被放入你的應用所在的 task 中。 取而代之的是,或是為瀏覽器啟動一個新的 task;或是瀏覽器已經在后台運行,只要把 task 調入前台來處理新 intent 即可。
無論 activity 是在一個新的 task 中啟動,還是位於其它已有的 task 中,用戶總是可以用回退鍵返回到前一個 activity 中。 但是,如果你啟動了一個啟動模式設為singleTask的 activity,且有一個后台 task 中已存在實例的話,則這個后台 task 就會整個轉到前台。 這時,當前的 back stack 就包含了這個轉入前台的 task 中所有的 activity,位置是在棧頂。下圖就展示了這種場景。
圖 . 啟動模式為“singleTask”的 activity 如何加入 back stack 的示意圖。 如果 activity 已經是在后台 task 中並帶有
自己的 back stack,則整個后台 back stack 都會轉入前台,並放入當前 task 的棧頂。