Activity的啓動模式和啓動流程

目錄

1.Android四種Activity啓動方式:

2.啓動模式的結構——棧(後進先出)

3.啓動方式詳解

3.1標準模式

3.2 singleTop模式(棧頂複用)

3.3singleTask模式(棧內複用)

3.4singleInstance模式(單例模式)

4.Activity啓動流程



1.Android四種Activity啓動方式:

  • 標準模式(standard)
  • 棧頂複用模式(singleTop)
  • 棧內複用模式(singleTask)
  • 單例模式(singleInstance)


啓動模式可在AndroidManifest.xml中,通過<activity>標籤的android:launchMode屬性設置。

2.啓動模式的結構——棧(後進先出)

任務棧(Task Stack)或者叫退回棧(Back Stack)介紹:

1.任務棧用來存放用戶開啓的Activity。

2.在應用程序創建之初,系統會默認分配給其一個任務棧(默認一個),並存儲根Activity。

3.同一個Task Stack,只要不在棧頂,就是onStop狀態:

4.任務棧的id自增長型,是Integer類型。

5.新創建Activity會被壓入棧頂。點擊back會將棧頂Activity彈出,併產生新的棧頂元素作爲顯示界面(onResume狀態)。

6.當Task最後一個Activity被銷燬時,對應的應用程序被關閉,清除Task棧,但是還會保留應用程序進程(狂點Back退出到Home界面後點擊Menu會發現還有這個App的框框。個人理解應該是這個意思),再次點擊進入應用會創建新的Task棧。

3.啓動方式詳解

3.1標準模式


        特點:1.Activity的默認啓動模式
                   2.每啓動一個Activity就會在棧頂創建一個新的實例。

 應用場景: 絕大多數Activity,mainfest中沒有配置就默認標準模式。如果以這種方式啓動的Activity被跨進程調用,在5.0之前新啓動的Activity實例會放入發送Intent的Task的棧的頂部,儘管它們屬於不同的程序,這似乎有點費解看起來也不是那麼合理,所以在5.0之後,上述情景會創建一個新的Task,新啓動的Activity就會放入剛創建的Task中,這樣就合理的多了。

  缺點:當Activity已經位於棧頂時,而再次啓動Activity時還需要在創建一個新的實例,不能直接複用。

3.2 singleTop模式(棧頂複用)


     如果需要新建的Activity位於任務棧棧頂,那麼此Activity的實例就不會重建,而是重用棧頂的實例。並回調如下方法: 由於不會重建一個Activity實例,則不會回調其他生命週期方法。

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
}        

應用場景:

  • 在通知欄點擊收到的通知,然後需要啓動一個Activity,這個Activity就可以用singleTop,否則每次點擊都會新建一個Activity。
  • 當然實際的開發過程中,測試妹紙沒準給你提過這樣的bug:某個場景下連續快速點擊,啓動了兩個Activity。如果這個時候待啓動的Activity使用 singleTop模式也是可以避免這個Bug的。同standard模式,如果是外部程序啓動singleTop的Activity,在Android 5.0之前新創建的Activity會位於調用者的Task中,5.0及以後會放入新的Task中。

3.3singleTask模式(棧內複用)

 

  • 特點:

 該模式是一種單例模式,即一個棧內只有一個該Activity實例。每次啓動Activity時系統首先檢查棧中是否存在當前Activity實例。如果存在則直接複用,並把當前Activity之上所有實例全部出棧

  • 應用場景:

大多數App的主頁。對於大部分應用,當我們在主界面點擊回退按鈕的時候都是退出應用,那麼當我們第一次進入主界面之後,主界面位於棧底,以後不管我們打開了多少個Activity,只要我們再次回到主界面,都應該使用將主界面Activity上所有的Activity移除的方式來讓主界面Activity處於棧頂,而不是往棧頂新加一個主界面Activity的實例,通過這種方式能夠保證退出應用時所有的Activity都能報銷燬。在跨應用Intent傳遞時,如果系統中不存在singleTask Activity的實例,那麼將創建一個新的Task,然後創建SingleTask Activity的實例,將其放入新的Task中。

  • 應用案例

例如瀏覽器的主界面。不管從多少個應用啓動瀏覽器,只會啓動主界面一次,其餘情況都會走onNewIntent,並且會清空主界面上面的其他頁面。

3.4singleInstance模式(單例模式)

 

  • 特點:

該模式的Activity會啓動一個新的任務棧來管理Activity實例,並且該實例在整個系統中只有一個。無論從那個任務棧                           中啓動該Activity,都會是該Activity所在的任務棧轉移到前臺,從而使Activity顯示。主要作用是爲了在不同程序中共享一個Activity。

  • 應用場景:

系統Launcher、鎖屏鍵、來電顯示等系統應用。

 

4.Activity啓動流程

(涉及源碼,我就不多贅述了,大致流程走一下)

  • Activity的啓動流程一般是通過調用startActivity或者是startActivityForResult來開始的
  • startActivity內部也是通過調用startActivityForResult來啓動Activity,只不過傳遞的requestCode小於0
  • Activity的啓動流程涉及到多個進程之間的通訊這裏主要是ActivityThread與ActivityManagerService之間的通訊
  • ActivityThread向ActivityManagerService傳遞進程間消息通過ActivityManagerNative,ActivityManagerService向ActivityThread進程間傳遞消息通過IApplicationThread。
  • ActivityManagerService接收到應用進程創建Activity的請求之後會執行初始化操作,解析啓動模式,保存請求信息等一系列操作。
  • ActivityManagerService保存完請求信息之後會將當前系統棧頂的Activity執行onPause操作,並且IApplication進程間通訊告訴應用程序繼承執行當前棧頂的Activity的onPause方法;
  • ActivityThread接收到SystemServer的消息之後會統一交個自身定義的Handler對象處理分發;
  • ActivityThread執行完棧頂的Activity的onPause方法之後會通過ActivityManagerNative執行進程間通訊告訴ActivityManagerService,棧頂Actiity已經執行完成onPause方法,繼續執行後續操作;
  • ActivityManagerService會繼續執行啓動Activity的邏輯,這時候會判斷需要啓動的Activity所屬的應用進程是否已經啓動,若沒有啓動則首先會啓動這個Activity的應用程序進程;
  • ActivityManagerService會通過socket與Zygote繼承通訊,並告知Zygote進程fork出一個新的應用程序進程,然後執行ActivityThread的mani方法;
  • 在ActivityThead.main方法中執行初始化操作,初始化主線程異步消息,然後通知ActivityManagerService執行進程初始化操作;
  • ActivityManagerService會在執行初始化操作的同時檢測當前進程是否有需要創建的Activity對象,若有的話,則執行創建操作;
  • ActivityManagerService將執行創建Activity的通知告知ActivityThread,然後通過反射機制創建出Activity對象,並執行Activity的onCreate方法,onStart方法,onResume方法;
  • ActivityThread執行完成onResume方法之後告知ActivityManagerService onResume執行完成,開始執行棧頂Activity的onStop方法;
  • ActivityManagerService開始執行棧頂的onStop方法並告知ActivityThread;
  • ActivityThread執行真正的onStop方法;


 

    2019.5.27更新

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章