圖解Android啓動模式

啓動模式分類

  1. standard: 標準模式
    此爲系統默認的啓動模式,每次啓動Activity均會新建一個實例。此種模式下,誰啓動了它,它就加入誰的任務棧中。
    如:
    A 啓動了 B,那麼B就加入到A所屬的任務棧中。
    A和B的生命週期如下。
    在這裏插入圖片描述
    非Activity的Context啓動Activity,會報錯,如下:
  Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

原因就是:非Activity的context沒有任務棧,而standard是要求加入啓動它的context所屬的任務棧。
解決方式就是 添加FLAG_ACTIVITY_NEW_TASK 標誌。

並不是所有的系統都會報這個錯誤,有些國內的手機上如小米,並不會報這個錯誤,而且能正常啓動,應該是系統做了優化。(參考紅米手機系統7.1.1)
四種啓動模式都會報這個錯誤

  • singleTop: 棧頂複用模式
    此模式下,如何Activity已經位於棧頂,則不會新建Activity,onNewIntent方法會被回調。
    在這裏插入圖片描述
    如果不在棧頂,就走正常的啓動流程。B爲singleTop模式,不在棧頂。
    在這裏插入圖片描述
  • singleTask: 棧內複用模式
    此模式下,只要棧內的存在此Activity,就不會新建。
    在這裏插入圖片描述
    B啓動C後,再啓動B,會把C銷燬掉,因爲singleTask默認具有clearTop的效果,會把B上邊的清掉。

如果CB都是singleTask, 當B啓動C,C在啓動B時,C會走onDestory.
如果CB都是singleInstance, 當B啓動C,C在啓動B時,C不會走onDestory.

  • singleInstance: 單實例模式
    具有singleTask的所有特性,並且,具有此屬性的Activity單獨位於一個棧中。
    在這裏插入圖片描述

    TaskAffinity

    用於標識Activity所需任務棧的名字,默認的名字時程序的包名。
    TaskAffinity主要和SingleTask啓動模式、allowTaskReparenting屬性配合使用。

  • TaskAffinity+SingleTask
    啓動的Activity會運行在TaskAffinity指定名稱的任務棧中。

  • TaskAffinity+ allowTaskReparenting
    允許該Activity從啓動它的任務棧中,轉移到與它有親密關係(affinity值也一樣)的任務中,當有親密關係的任務再次啓動時。
    如:
    應用A的主Activity是Activity_A,應用B的主Activity是Activity_B,以及普通的Activity_B_1
    操作流程:Activity_A 啓動了Activity_B_1,然後返回桌面,點擊應用B的圖標。

    1. allowTaskReparenting = true
      此時點擊應用B的圖標後會進入Activity_B_1
      因爲,Activity_A啓動Activity_B_1後,任務棧爲Activity_A 、 Activity_B_1,當應用B啓動後,系統發現Activity_B_1所屬的任務棧已經存在,就把Activity_B_1移到所屬的任務棧中,所以呈現出來的是Activity_B_1。
    2. allowTaskReparenting = false
      此時點擊應用B的圖標後會進入Activity_B
      因爲,Activity_A啓動Activity_B_1後,任務棧爲Activity_A 、 Activity_B_1,當應用B啓動後,發現沒有相同的任務棧,所以新建一個任務棧,並把Activity_B放入。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章