Android開發筆記(十六)——Activity的4種啟動模式
阿新 • • 發佈:2020-07-21
AndroidManifest
中比較重要的一個屬性是 launchMode
啟動模式:
Acyivity的 android:launchMode
四個屬性:
- standard:標準模式,預設
- singleTop:Task棧頂複用模式(棧是先進後出,當我們啟動一個Activity,如果這個目標Activity位於棧頂,不會建立一個新的例項,而是會直接複用這個棧頂的Activity)
- singleTask:Task棧內複用模式(不一定要在棧頂,只要棧內有就可以直接複用,不管位置)
- singleInstance:全域性單例模式(前兩個必須是在同一個棧內,這個是隻要在存取的所有棧裡面只要有的就可以複用)
測試準備:
繼續使用上次建立的AActivity和BActivity。
在AActivity中的onCreate函式中新增:
Log.d("AActivity","-----onCreate-----");
Log.d("AActivity","---taskid:"+getTaskId()+"--- ---hash:"+hashCode()+"---");
logtaskName(); //列印任務棧的名稱
onNewIntent
和 logtaskName
函式寫在onCreate函式後面:
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Log.d("AActivity","-----onNewIntent-----"); Log.d("AActivity","---taskid:"+getTaskId()+"--- ---hash:"+hashCode()+"---"); logtaskName(); //列印任務棧的名稱 } private void logtaskName(){ try { ActivityInfo info = getPackageManager().getActivityInfo(getComponentName(), PackageManager.GET_META_DATA); Log.d("AActinity",info.taskAffinity); //info.taskAffinity可以理解為當前Activity所在任務棧的名稱 } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } }
在BActivity中同樣操作,在A新增一個Button使其在A頁面跳轉到A頁面,在B新增一個Button使其在B頁面跳轉到A頁面。
standard
- Activity是由任務棧管理的,每啟動一個Activity,就會被放入棧中,按返回鍵,就會從棧頂移除一個Activity。
- standard是預設的啟動模式,即標準模式。每啟動一個Activity,都會建立一個新的例項。
演示:
- 從主頁面MainActivity跳轉到AActivity中時,MainActivity的任務棧為包名,後面所有的Activity都隸屬於這個棧
- 當沒有設定任務棧的名稱時候,預設為應用的包名
- 當點選Button從A頁面跳轉到A頁面時,這裡taskid是一樣的,也就是這兩個Activity處在同一個任務棧當中,但是他們的雜湊碼是不一樣的,表示這兩個Activity不是同一個例項,說明從A頁面跳轉到A頁面時又建立了一個新的例項。(因為是標準啟動,每啟動一個Activity,都會建立一個新的例項)
- 當點選Jump從A頁面跳轉到B頁面時:可以看到任務棧還是相同的,但是雜湊碼不同,因為BActivity本身不存在於任務棧當中,是一個新的例項
singleTop
- 當要啟動的目標Activity已經位於棧頂時,不會建立新的例項,會複用棧頂的Activity,並且其
onNewIntent()
方法會被呼叫; - 如果目標Activity不在棧頂(在棧裡但不在頂部;或者根本不在棧內),則和standard一樣建立新的例項。
演示:
- 從主頁面MainActivity跳轉到AActivity中時,呼叫onCreate方法
- 從AActivity再次跳轉到AActivity中時(此時目標Activity是AActivity,目標Activity在棧頂中),這時打印出來的雜湊碼和之前一直,也就是說此時複用了棧頂的Activity,並且其onNewIntent()方法被呼叫
- 從AActivity跳轉到BActivity中時(此時目標Activity是BActivity,目標Bctivity不在棧中),此時雜湊碼發生了變化,說明建立了新的例項。
- 從BActivity再次跳轉到AActivity中時(此時目標Activity是AActivity,目標Activity在棧中但是不在棧頂中),此時雜湊碼發生了變化,說明建立了新的例項。
singleTask
- 在同一個任務棧中,如果要啟動的目標Activity已經在棧中,則會複用該Activity,並呼叫其
onNewIntent()
方法,並且該Activity上面的Activity會被清除(出棧); - 如果棧中沒喲,則建立新的例項。
當沒有設定任務棧的名稱時候,預設為應用的包名,如果自己有設定任務棧名稱(在 AndroidManifast
中對應的activity設定屬性 android:taskAffinity
),那就不屬於預設包名的任務棧了。當從這個Activity開始啟其他Activity時候,都會被加入這個新設定的棧中。
singleInstance
- 全域性複用,不管哪個Task棧,只要存在目標Activity就複用;
- 每個Activity佔有一個新的Task棧。
通常使用standard和singleTop、singleTask,singleInstance用的比較少。