理解Android的四種啟動模式

靈劍山真人發表於2021-12-29

一:前言

四種模式分別為standard, singleTop, singleTask, singleInstance。自己應該明確一個概念先,single到底要single什麼。每一個應用app都有一個包名,然後每一個應用都會有一個task,這個task和包名對應起來,如果要建立一個新task,名字就得不一樣。

  • 一個應用會有一個包名,應用中預設有一個以包名為名字的task
  • task是一個概念,實現是stack棧。
  • task用來管理activity,一個activity轉到另一個activity,就會把新activity壓棧,遵循先進後出。
  • task中的activity可以跨應用,比如說app中跳轉到微信,然後按返回鍵又可以回到自己那個應用。

 

 

二:如何改變啟動模式

  1. 在manifest中對activity設定
  2. 更改Intent啟動activity時的flag

 

三:直接從singleTop開始

三個activity,activity1可以跳轉到activity2,activity2可以跳轉到activity3.

1:第一種情況,棧頂已有例項

棧底---------------------------------------》棧頂
acitivity1     activity2    acitivity3   

這時候以singleTop模式啟動activity3,重用舊例項, 備註:順便呼叫activity3的onNewIntent()方法

棧底---------------------------------------》棧頂
acitivity1     activity2    acitivity3  

2:第二種情況,棧頂沒有例項

棧底---------------------------------------》棧頂
acitivity1    acitivity3    activity2

這時候以singleTop模式啟動activity3,建立新例項

棧底---------------------------------------》棧頂
acitivity1    acitivity3    activity2  activity3(new)

 

 

四:很簡單的singleTask

注意要在manifest中設定

android:launchMode="singleTask"

(我發現設不設定intent的flag都沒用,關鍵是設定這個,只設定flag沒有用)

1:第一種情況,在manifest中沒有設定了taskAffinity

當前task沒有這個activity的例項就建立一個,放在棧頂;若是有例項,就把那個例項上面的activity全部出棧(銷燬),並呼叫要啟動的activity例項的:onRestart, onStart, onResume

棧底---------------------------------------》棧頂
acitivity1    acitivity3    activity2

這時候以singleTast模式啟動activity3,但沒有taskAffinit
會把已有的activity3上面的activity,即activity2出棧,銷燬
並呼叫已有的activity3的onRestart,onStart, onResume

棧底---------------------------------------》棧頂
acitivity1    acitivity3 (old)

即singleTask確保在當前task例項唯一

 

2:第二種情況,在manifest中設定了taskAffinity

2.1:這個task已被建立

棧底---------------------------------------》棧頂

task1:
acitivity1    acitivity3    activity2

task2:
acitivity1    acitivity3    activity2

以singleTask模式啟動activity3,指定task2,表現和第一種情況一樣
把上面的activity都出棧

task1:
acitivity1    acitivity3    activity2

task2:
acitivity1    acitivity3(old)

2.2:這個task未被建立

棧底---------------------------------------》棧頂

task1:
acitivity1    acitivity3    activity2


以singleTask模式啟動activity3,指定task2
會建立task2,並建立新例項放進去

task1:
acitivity1    acitivity3    activity2

task2:
activity3(new)

ps:之後activity3啟動的其他activity,除非新指定task,否則都在activity3所在的棧中了,即所謂嫁雞隨雞嫁狗隨狗


singleTask名字誤導很大,我覺得名字為singleAtTask更貼切。

 

五:更簡單的singleInstance

啟動模式為singleInstance的activity,在整個手機中,只能有一個例項,再次呼叫的時候,會找到這個例項並把它調到前臺

比如說activity1已singleInstance模式啟動,那就把它調到前臺(已存在的話)。

  • activity1屬於一個唯一的task,這個task只有它一個
  • activity1啟動其他activity,若這個activity指明taskAffinit(即使不是singleTask模式),就在指明的task中建立,若沒有指明taskAffinit,就預設找應用包名的task。這邊邏輯和singleTask很像了。

 

 

 

 

 

參考資料:https://blog.csdn.net/zhangjg_blog/article/details/10923643

     https://www.kancloud.cn/alex_wsc/android_art/1828110

相關文章