一、app的啟動流程包括的步驟
1、創(chuàng)建進程
App發(fā)起進程:當從桌面啟動應用,則發(fā)起進程便是Launcher所在進程;當從某App內(nèi)啟動遠程進程,則發(fā)送進程便是該App所在進程。發(fā)起進程先通過binder發(fā)送消息給system_server進程。system_server進程:調(diào)用Process.start()方法,通過socket向zygote進程發(fā)送創(chuàng)建新進程的請求。zygote進程:在執(zhí)行ZygoteInit.main()后便進入runSelectLoop()循環(huán)體內(nèi),當有客戶端連接時便會執(zhí)行ZygoteConnection.runOnce()方法,再經(jīng)過層層調(diào)用后fork出新的應用進程。新進程:執(zhí)行handleChildProc方法,最后調(diào)用ActivityThread.main()方法。2、綁定Application
上面創(chuàng)建進程后,執(zhí)行ActivityThread.main()方法,隨后調(diào)用attach()方法。將進程和指定的Application綁定起來。這個是通過ActivityThread對象中調(diào)用bindApplication()方法完成的,該方法發(fā)送一個BIND_APPLICATION的消息到消息隊列中,最終通過handleBindApplication()方法處理該消息,然后調(diào)用makeApplication()方法來加載App的classes到內(nèi)存中。
二、App啟動方式
1、冷啟動
當啟動應用時,后臺沒有該應用的進程,這時系統(tǒng)會重新創(chuàng)建一個新的進程分配給該應用,這個啟動方式就是冷啟動。冷啟動因為系統(tǒng)會重新創(chuàng)建一個新的進程分配給它,所以會先創(chuàng)建和初始化Application類,再創(chuàng)建和初始化MainActivity類(包括一系列的測量、布局、繪制),最后顯示在界面上。
2、熱啟動
當啟動應用時,后臺已有該應用的進程(例:按back鍵、home鍵,應用雖然會退出,但是該應用的進程是依然會保留在后臺,可進入任務(wù)列表查看),所以在已有進程的情況下,這種啟動會從已有的進程中來啟動應用,這個方式叫熱啟動。熱啟動因為會從已有的進程中來啟動,所以熱啟動就不會走Application這步了,而是直接走MainActivity(包括一系列的測量、布局、繪制),所以熱啟動的過程只需要創(chuàng)建和初始化一個MainActivity就行了,而不必創(chuàng)建和初始化Application,因為一個應用從新進程的創(chuàng)建到進程的銷毀,Application只會初始化一次。
三、影響APP啟動性能的因素
1、密集型應用初始化
如果您在代碼中替換了Application對象,且在Application對象進行初始化的時候執(zhí)行了密集的工作或者復雜的邏輯,那么您的啟動性能就會受到影響。如果您的應用子類執(zhí)行尚不需要完成的初始化,則應用可能會在啟動過程中浪費更多的時間,并且有些初始化可能是完全不必要的。
如果Application 里面的初始化操作不結(jié)束的話,其他任意的程序操作都是無法進行的。因此,在 Application 初始化的地方做太多密集的工作或者復雜的邏輯是導致啟動性能問題的元兇之一。
在做 Application的初始化工作時,很多組件是需要我們區(qū)別對待的,有些組件適合做延遲加載,有些則適合放到其他的地方做初始化操作,在此我們需要特別留意包含 Disk IO的操作,因為網(wǎng)絡(luò)訪問等嚴重耗時的任務(wù),是會嚴重影響程序啟動的。
2、密集型 Activity 初始化
我們在創(chuàng)建 Activity 時通常需要開展大量的高開銷工作,用來提升 Activity 的創(chuàng)建速度,因為提升 Activity 的創(chuàng)建速度是優(yōu)化 APP 啟動速度的首要目標。從桌面點擊 APP 圖標啟動應用開始,程序會顯示一個啟動窗口等待 Activity 的創(chuàng)建加載完畢再進行顯示。在 Activity 的創(chuàng)建加載過程中,應用會執(zhí)行很多的操作,例如設(shè)置頁面的主題,初始化頁面的布局,加載圖片,獲取網(wǎng)絡(luò)數(shù)據(jù),讀寫 Preference 等等。
上述操作的任何一個環(huán)節(jié)出現(xiàn)性能問題都可能導致畫面不能及時顯示,從而影響應用程序的啟動速度。
延伸閱讀1:密集型應用初始化導致app啟動性能差的解決方法
優(yōu)化這些問題的解決方案是給應用做延遲加載處理,可以在 Application 里面做延遲加載,也可以將一些初始化的操作延遲到組件真正被調(diào)用的時候再做加載。例如,不創(chuàng)建全局靜態(tài)對象,而是轉(zhuǎn)為單例模式,其中應用僅在名列前茅次訪問對象時初始化它們。