重溫Android四大元件(二)—Activity的啟動模式與標誌位

Codeing_ls發表於2019-05-07

前言

重溫Android四大元件的第二篇,主要總結Activity的啟動模式以及相關的標誌位。Activity啟動模式是Activity的一個重要的屬性,啟動模式決定了Activity在Activity棧的存在的行為。不同的啟動模式下的Activity有不同的表現,所以開發者需要搞清楚各個啟動模式的特性以及相互之間的區別。

Activity的啟動模式

  • standard(標準模式):這是系統預設的啟動模式。每次啟動standard模式的Activity不管在Activity棧中是否存在Activity的例項,都會建立一個新的Activity例項。另外,被啟動的Activity會在啟動它的Activity所在的棧中存在。

  • singleTop(棧頂複用模式):在這種模式下啟動Activity,如果被啟動的Activity例項位於當前棧的棧頂,那麼將複用棧頂的Activity例項。否則,重新建立一個Activity例項。在上節講過,如果複用Activity例項,將呼叫onNewIntent方法,而不是重建Activity。

  • singleTask(棧內複用模式):在這種模式下啟動Activity系統會建立新的Activity棧用來例項化Activity例項(預設情況下,Activity會在啟動它的Activity棧中例項化)。如果Activity棧中存在Activity例項,就會複用Activity例項,同時從onNewIntent方法開始Activity的生命週期,同時singleTask模式下的Activity帶有clearTop的效果,也就是說複用棧中Activity例項的時候會將位於當前Activity例項上面的Activity例項銷燬。

  • singleInstance(單例項模式):在這種模式下啟動Activity是系統會建立一個新的Activity棧並且這個棧中只存在這一個Activity例項。

standard模式下的Activity在棧中的表現

在standard模式下的Activity的特性是每次啟動Activity時都會建立新的Activity例項。比如在棧A中已經存在一個standard模式的Activity_A,此時啟動Activity_B,那麼棧中的情況就是B-A。如果再次啟動A,將會重建A的例項,此時棧中情況是A-B-A。同時按下返回鍵時會銷燬棧頂的Activity,然後將下一個Activity提到前臺。如果棧已經不存在Activity例項那麼會立即銷燬棧。

重溫Android四大元件(二)—Activity的啟動模式與標誌位

singleTop模式下的Activity在棧中的表現

在singleTop模式下Activity的主要特性是可以複用在棧頂的Activity例項。比如棧中已經存在Activity_A和singleTop模式的Activity_B例項,此時如果再次啟動Activity_B那麼將複用Activity_B的例項,並且Activity_B的生命週期從onNewIntent開始。如果情況顛倒過來,Activity_A的啟動模式是singleTop但Activity_A不位於棧頂,那麼在啟動Activity_A時,將會重新建立Activity_A的例項。此時棧中的情況是A-B-A。

重溫Android四大元件(二)—Activity的啟動模式與標誌位

singleTask模式下啟動Activity在棧中的表現

在singleTask模式下Activity主要有可複用的特性,如果棧記憶體在將要啟動的Activity例項那麼將複用該Activity例項。比如:在前臺的棧中有Activity1和Activity2,在另外一個棧中有Activity3和Activity4,其中Activity3是singleTask啟動模式,如果啟動Activity3,由於棧中存在Activity3的例項,那麼將複用Activity3的例項。同時singleTask模式的Activity例項還有棧頂清除特點,那麼Activity4的例項將被清除。

重溫Android四大元件(二)—Activity的啟動模式與標誌位

singleInstance模式下啟動Activity在棧中的表現

singleInstance是一種單例項模式,在這種模式下啟動的Activity的每次都會建立一個新的Activity棧,並且在棧中建立Activity的例項。

重溫Android四大元件(二)—Activity的啟動模式與標誌位

Activity的啟動標誌位

Activity的啟動標誌位有很多,這裡分析一些常用的標誌位。設定啟動模式的標誌位:FLAG_ACTIVITY_NEW_TASK、FLAG_ACTIVITY_SINGLE_TOP。設定Activity行為的標誌位:FLAG_ACTIVITY_CLEAR_TOP。

FLAG_ACTIVITY_NEW_TASK:通過在Intent中加入FLAG_ACTIVITY_NEW_TASK啟動Activity時,將在指定的Activity棧中啟動Activity,如果棧中已經存在Activity例項,將複用例項,並且呼叫onNewIntent方法,這個過程跟singleTask模式下的Activity表現相同。

FLAG_ACTIVITY_SINGLE_TOP:通過在Intent中加入FLAG_ACTIVITY_SINGLE_TOP啟動Activity時,如果棧頂已經存在Activity例項,將複用Activity例項,並且呼叫onNewIntent方法。否則將重新建立Activity例項。這個過程跟singleTop模式下的Activity表現相同。

FLAG_ACTIVITY_CLEAR_TOP:如果正在啟動的Activity已在當前棧中執行,則不會啟動該活動的新例項,而是銷燬其上的所有其他活動。如果Activity的啟動模式是singleTask,那麼將呼叫onNewIntent方法。如果Activity的啟動模式是standard那麼會把Activity已經它上面的Activity例項一同銷燬,並且重建Activity例項放入棧頂。

Manifest檔案中的標誌位

在Manifest檔案中也有定義Activity的行為的標誌位,但是Intent中的標誌位的優先順序高於Manifest檔案中的標誌位。

  • lanuchMode:啟動模式標誌位,可以定義Activity的啟動模式。預設為standard模式。

  • taskAffinity:定義Activity的棧,啟動Activity時會根據定義的棧名稱建立任務棧並且在棧中建立Activity例項。

  • allowTaskReparenting:預設為false。當設定為true的時候,在這種情況下Activity可以從啟動它的棧中轉移到它原本所在的應用程式的棧中。比如:有兩個應用A和應用B,應用B擁有一個該屬性設定為true的Activity。在一個應用A呼叫這個應用B的Activity,然後在開啟應用B時,這個Activity會轉移到這個應用B的棧中。

  • clearTaskOnLaunch:是否每當從主螢幕重新啟動棧時都從中移除根 Activity 之外的所有 Activity —“true”表示始終將任務清除到只剩其根 Activity;“false”表示不做清除。 預設值為“false”。該屬性只對啟動新棧的 Activity(根 Activity)有意義;對於棧中的所有其他Activity,均忽略該屬性。當值為“true”時,每次使用者再次啟動棧時,無論使用者最後在棧中正在執行哪個 Activity,也無論使用者是使用返回還是主螢幕按鈕離開,都會將使用者轉至棧的根 Activity。

  • alwaysRetainTaskState:系統是否始終保持 Activity 所在任務的狀態 —“true”表示保持,“false”表示允許系統在特定情況下將任務重置到其初始狀態。 預設值為“false”。該屬性只對任務的根 Activity 有意義;對於所有其他 Activity,均忽略該屬性。正常情況下,當使用者從主螢幕重新選擇某個任務時,系統會在特定情況下清除該任務(從根 Activity 之上的堆疊中移除所有 Activity)。系統通常會在使用者一段時間(如30分鐘)內未訪問任務時執行此操作。不過,如果該屬性的值是“true”,則無論使用者如何到達任務,將始終返回到最後狀態的任務。 例如,在網路瀏覽器這類存在大量使用者不願失去的狀態(如多個開啟的標籤)的應用中,該屬性會很有用。

總結

上面介紹了Activity的啟動模式、標誌位以及Manifest檔案中的標誌位。通過學習這些內容可以掌握Activity在不同設定下的行為表現,也能通過使用這些設定來實現所需的功能。

相關文章