Activity
Activity 是在開發 Android APP 時,第一個會遇到的 component,每一個頁面基本上都是一個獨立的 Activity。
在使用 Activity 時,有一個很重要的部份就是如果開啓 Activity 以及該 Activity 結束後會去哪裡?
第一個 Activity
在手機開機後,第一個 Activity 就是 Lock Screen,解鎖後就是進入 Home Screen 的 Activity。
假設我們點擊在 Home Screen 上的 Gmail 圖示,就是進入 Gmail APP 並開啓 Gmail Main Activity。並且進入到某一封信中。
這時,如果回到 Home Screen 開啓 Facebook APP時,也會進入 Facebook Main Activity。然後在 2 個 APP 中交叉使用,可以看到 Android 會各自記住每個 APP 目前是停留在哪一個 Activity,以及前一個 Activity 或是前5個 Activity 的歷程。
那 Android 是怎麼管理每個 APP 的 Activity ?
Task
每個 APP 在一開始啓動時,Android 就會幫該 APP 建立一個名為 Task 的 Back Stack 來記錄 Activity 的使用記錄,並且把 Main Activity 放入 Stack 中。
當使用者在 Main Activity 操作開啓 Second Activity 時,Second Activity 會被放在 Stack 中最上層的位置。
當使用者按下 Back Button 關閉 Second Activity 時,會把 Stack 中的 Second Activity 移除,而被壓在下面的 Main Activity 就會顯示在畫面上。
在 Stack 中的 Activity 不會被重新排序,只會被以後進先出的方式進行 Push 跟 Pop。
那不同的 Task 間如何互動?
當使用者按下 Home Button 回到 Home Screen 時,原本的 Task 會被完整的存在放 Background,而 Task 中的 Activity 都會進入 Stop 的狀態。
回到 Task 時,原本 Activity 的歷程都會被保留下來並顯示離開前最後的 Activity。
Intent
Activity 可以使用以下的程式開啓另一個 Activity。
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
這看起來很單純,但是難的部份是像以下的歷程
Main > A > B > A > B > A > C
當使用者在 C 時,需要按幾次 Back Button 後才能回到 Main 呢?
在預設每次開啓 A 都是全新的 A,所以需要按 6 次才能回到 Main。
但是有時 A 與 B 是切換的關係,可能是同樣的列表但不同的顯示方式,C是列表中某筆詳細資料,這時,使用者會預期他只需要按 2 次 Back Button 就能回到 Main 了。
Activity 的一個 launcheMode 的屬性是用來規定該 Activity 啓動的方式。
設定 LaunchMode 的兩種方法
- 在 manifest 檔案中的 Activity Tag 來設定
- 在 Intent 加入 Flag 來設定
當同時設定時,會以 Intent 中的 Flag 為最後的設定。
在 manifest 檔案中設定 launchMode
<activity android:name=".activities.MainActivity"
android:launchMode="standard" />
standard
每次開啓 Activity 都是一個全新的頁面
singleTop
如果該 Activity 目前在 Task 的最上層,則不會再建立一個新的 Activity 而會直接使用目前已建立好的 Activity 並呼叫 Activity 中的 onNewIntent 函式。
如果目前該 Activity 並沒有被開啓,就會在目前的 Task 新建一個全新的 Activity。
singleTask
Android 會新建一個全新的 Task , 然後在剛建好的 Task 中建立一個全新的 Activity。
如果該 Activity 已經被建立了,就會直接使用目前已建立好的 Activity 並呼叫 Activity 中的 onNewIntent 函式。
singleInstance
跟 singleTask 大致上一樣,不過 Android 不會把其它 Activity 加入到目前的 Task。
在 Intent 加入 Flag 設定 launchMode
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
FLAG_ACTIVITY_NEW_TASK
跟 singleTask 一樣
FLAG_ACTIVITY_SINGLE_TOP
跟 singleTop 一樣
FLAG_ACTIVITY_CLEAR_TOP
如果該 Activity 已經被建立了,就會直接使用目前已建立好的 Activity 並呼叫 Activity 中的 onNewIntent 函式,並且把疊在該 Activity 以上的其它 Activity 都清掉。
Activity Lifecycle
最後,下面這張圖解釋了在 Activity 相互切換時,在什麼時間點哪些 Function 會被呼叫到。
參考網頁
Task and Back Stack - 官方文件,必看。
Manipulating Android tasks and back stack
Managing Activity Backstack - 用圖解的方式解釋 launchMode,推薦看。
0 意見:
張貼留言