1.叨叨
上篇說了幾種常見的應用,但總感覺不太舒服,這篇將通過 A,B,C,D 四個界面解析;
2.瞭解 LaunchMode
在 AndroidManifest.xml
中配置 activity
的時候的一個屬性,比如:
<activity
android:name=".OnePageActivity"
// i'm here
android:launchMode="standard"
android:taskAffinity="cn.labelnet.task" />
比如:
如圖所示: 一共四個值
- singleTask
- singleInstance
- singleTop
- standard
這四個值只用在 activity 啓動的時候才能起作用
其中
- singleTop 和 standard 可以被實例化多次,實例可以屬於多個 task , 可以處於任何 back stack
- singleTask 和 singleInstance 不可以被實例化多次,常用語一個 task 堆棧,處於 back stack 開始部分
2.1 singleTop
當進入A頁面的時候系統會自動 在 Task
堆棧中檢測當前棧頂元素是否是我們需要訪問的A頁面的Activity
,如果棧頂元素是我們的A頁面,那麼將重用A頁面, 同時回調 onNewIntent()
函數
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
比如 :
堆棧頁面順序爲 A,B,C,D 在 D頁面中跳轉 D頁面, 會重用D實例,順序還爲 A,B,C,D
2.2 standard
普通堆棧模式,默認模式,可以不寫;
當前堆棧順序爲 A,B,C , 在C中進入D頁面,則順序爲 A,B,C,D
2.3 SingleTask
此模式,不會重建新的實例,如果訪問這個實例,會將這個實例上面的堆棧清除掉;
當前堆棧順序爲 A,B,C,D , A頁面被修飾爲SingleTask, 在D中進入B頁面 ,則當前堆棧信息爲 A,B
2.4 SingleInstance
此模式,將會重建新的堆棧信息,並脫離當前 task 堆棧
當前堆棧順序爲 A,B,C , 在C頁面進入被修飾的D頁面時,當前的堆棧信息爲兩個:
Task : A,B,C 和 Task : D
3.Intent Flag 跳轉說明
- setFlag() 設置新的 flag
- addFlag() 在當前的 flag 上添加其它 flag
3.1 FLAG_ACTIVITY_NEW_TASK
默認類型,重新創建實例;
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
當前的堆棧順序爲 A,B , 如果在B上進入C , 那麼當前順序爲 A,B,C
如果配合 android:taskAffinity
使用,會創建新的實例在新的堆棧中;
<activity
android:name=".C"
android:taskAffinity="cn.labelnt.task"
/>
當前堆棧順序爲 A,B , 如果在B上進入C ,則當前的堆棧順序爲 Task 1 : A,B 和 Task 2 : C
3.2 FLAG_ACTIVITY_SINGLE_TOP
這種模式和 Launch Mode
的 single top
設置是一樣的
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
堆棧頁面順序爲 A,B,C,D 在 D頁面中跳轉 D頁面, 會重用D實例,順序還爲 A,B,C,D
3.3 FLAG_ACTIVITY_CLEAR_TOP
這種模式和 LaunchMode
的 single task
設置是一樣的;
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
當前堆棧順序爲 A,B,C,D , A頁面被修飾爲SingleTask, 在D中進入B頁面 ,則當前堆棧信息爲 A,B
合併使用
如果在返回 B 頁面,不想 B 頁面重新創建,需要設置 Single Top :
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
}
會重新回調 B 頁面的 onNewIntent() 方法;
3.4 FLAG_ACTIVITY_NO_HISTORY
當前進入的頁面不會加入堆棧中,而在其上面啓動的會加入到棧中
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}
當前堆棧順序爲 A,B , 如果C頁面被修飾,在B頁面啓動C頁面,那麼當前的堆棧順序還爲 A ,B
如果在C上打開D頁面,D頁面未被修飾,那麼當前的堆棧順序爲 A,B,D
3.5 FLAG_ACTIVITY_BROUGHT_TO_FRONT
這個模式和standard 模式一樣,普通堆棧
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
startActivity(intent);
}
當前堆棧順序爲 A,B,C , 在C中進入D頁面,則順序爲 A,B,C,D
3.6 FLAG_ACTIVITY_REORDER_TO_FRONT
可以改變堆棧順序,如果當前堆棧中存在,會取到 top 上,執行 restart() - onstart() - onResume()
並執行回調 onNewIntent() 方法;
private void moveNewTask(Class<?> cls) {
Intent intent = new Intent(this, cls);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
當前堆棧順序爲 A,B,C,D , 如果在 D 中啓動 B , 那麼堆棧順序變爲 A,C,D,B