Android優(yōu)化應(yīng)用啟動(dòng)速度
一、應(yīng)用的啟動(dòng)
啟動(dòng)方式
通常來(lái)說(shuō),在安卓中應(yīng)用的啟動(dòng)方式分為兩種:冷啟動(dòng)和熱啟動(dòng)。
- 1、冷啟動(dòng):當(dāng)啟動(dòng)應(yīng)用時(shí),后臺(tái)沒(méi)有該應(yīng)用的進(jìn)程,這時(shí)系統(tǒng)會(huì)重新創(chuàng)建一個(gè)新的進(jìn)程分配給該應(yīng)用,這個(gè)啟動(dòng)方式就是冷啟動(dòng)。
- 2、熱啟動(dòng):當(dāng)啟動(dòng)應(yīng)用時(shí),后臺(tái)已有該應(yīng)用的進(jìn)程(例:按back鍵、home鍵,應(yīng)用雖然會(huì)退出,但是該應(yīng)用的進(jìn)程是依然會(huì)保留在后臺(tái),可進(jìn)入任務(wù)列表查看),所以在已有進(jìn)程的情況下,這種啟動(dòng)會(huì)從已有的進(jìn)程中來(lái)啟動(dòng)應(yīng)用,這個(gè)方式叫熱啟動(dòng)。
特點(diǎn)
1、冷啟動(dòng):冷啟動(dòng)因?yàn)橄到y(tǒng)會(huì)重新創(chuàng)建一個(gè)新的進(jìn)程分配給它,所以會(huì)先創(chuàng)建和初始化Application類(lèi),再創(chuàng)建和初始化MainActivity類(lèi)(包括一系列的測(cè)量、布局、繪制),最后顯示在界面上。
2、熱啟動(dòng):熱啟動(dòng)因?yàn)闀?huì)從已有的進(jìn)程中來(lái)啟動(dòng),所以熱啟動(dòng)就不會(huì)走Application這步了,而是直接走M(jìn)ainActivity(包括一系列的測(cè)量、布局、繪制),所以熱啟動(dòng)的過(guò)程只需要?jiǎng)?chuàng)建和初始化一個(gè)MainActivity就行了,而不必創(chuàng)建和初始化Application,因?yàn)橐粋€(gè)應(yīng)用從新進(jìn)程的創(chuàng)建到進(jìn)程的銷(xiāo)毀,Application只會(huì)初始化一次。
上面說(shuō)的啟動(dòng)是點(diǎn)擊app的啟動(dòng)圖標(biāo)來(lái)啟動(dòng)的,而另外一種方式是進(jìn)入最近使用的列表界面來(lái)啟動(dòng)應(yīng)用,這種不應(yīng)該叫啟動(dòng),應(yīng)該叫恢復(fù)。
二、應(yīng)用啟動(dòng)的流程
在安卓系統(tǒng)上,應(yīng)用在沒(méi)有進(jìn)程的情況下,應(yīng)用的啟動(dòng)都是這樣一個(gè)流程:當(dāng)點(diǎn)擊app的啟動(dòng)圖標(biāo)時(shí),安卓系統(tǒng)會(huì)從Zygote進(jìn)程中fork創(chuàng)建出一個(gè)新的進(jìn)程分配給該應(yīng)用,之后會(huì)依次創(chuàng)建和初始化Application類(lèi)、創(chuàng)建MainActivity類(lèi)、加載主題樣式Theme中的windowBackground等屬性設(shè)置給MainActivity以及配置Activity層級(jí)上的一些屬性、再inflate布局、當(dāng)onCreate/onStart/onResume方法都走完了后最后才進(jìn)行contentView的measure/layout/draw顯示在界面上,所以直到這里,應(yīng)用的第一次啟動(dòng)才算完成,這時(shí)候我們看到的界面也就是所說(shuō)的第一幀。
所以,總結(jié)一下,應(yīng)用的啟動(dòng)流程如下:
Application的構(gòu)造器方法——>attachBaseContext()——>onCreate()——>Activity的構(gòu)造方法——>onCreate()——>配置主題中背景等屬性——>onStart()——>onResume()——>測(cè)量布局繪制顯示在界面上。
三、測(cè)量應(yīng)用啟動(dòng)的時(shí)間
在上面這個(gè)啟動(dòng)流程中,任何一個(gè)地方有耗時(shí)操作都會(huì)拖慢我們應(yīng)用的啟動(dòng)速度,而應(yīng)用啟動(dòng)時(shí)間是用毫秒度量的,對(duì)于毫秒級(jí)別的快慢度量我們還是需要去精確的測(cè)量到到底應(yīng)用啟動(dòng)花了多少時(shí)間,而根據(jù)這個(gè)時(shí)間來(lái)做衡量。
什么才是應(yīng)用的啟動(dòng)時(shí)間
從點(diǎn)擊應(yīng)用的啟動(dòng)圖標(biāo)開(kāi)始創(chuàng)建出一個(gè)新的進(jìn)程直到我們看到了界面的第一幀,這段時(shí)間就是應(yīng)用的啟動(dòng)時(shí)間。
我們要測(cè)量的也就是這段時(shí)間,測(cè)量這段時(shí)間可以通過(guò)adb shell命令的方式進(jìn)行測(cè)量,這種方法測(cè)量的最為精確,命令為:
adb shell am start -W [packageName]/[packageName.MainActivity]
執(zhí)行成功后將返回三個(gè)測(cè)量到的時(shí)間:
1、ThisTime:一般和TotalTime時(shí)間一樣,除非在應(yīng)用啟動(dòng)時(shí)開(kāi)了一個(gè)透明的Activity預(yù)先處理一些事再顯示出主Activity,這樣將比TotalTime小。
2、TotalTime:應(yīng)用的啟動(dòng)時(shí)間,包括創(chuàng)建進(jìn)程+Application初始化+Activity初始化到界面顯示。
3、WaitTime:一般比TotalTime大點(diǎn),包括系統(tǒng)影響的耗時(shí)。
下面是測(cè)量一個(gè)應(yīng)用冷啟動(dòng)和熱啟動(dòng)的時(shí)間:
冷啟動(dòng):

熱啟動(dòng):

可以看到在進(jìn)程已經(jīng)存在的情況下,只需要重新初始化MainActivity,這樣的啟動(dòng)比較快,不過(guò)大多數(shù)情況下應(yīng)用的啟動(dòng)都是冷啟動(dòng),因?yàn)橛脩?hù)都會(huì)在任務(wù)列表中手動(dòng)關(guān)閉遺留的應(yīng)用進(jìn)程。
四、減少應(yīng)用啟動(dòng)時(shí)的耗時(shí)
針對(duì)冷啟動(dòng)時(shí)候的一些耗時(shí),如上測(cè)得這個(gè)應(yīng)用算是中型的app,在冷啟動(dòng)的時(shí)候耗時(shí)已經(jīng)快700ms了,如果項(xiàng)目再大點(diǎn)在Application中配置了更多的初始化操作,這樣將可能達(dá)到1s,這樣每次啟動(dòng)都明顯感覺(jué)延遲,所以在進(jìn)行應(yīng)用初始化的時(shí)候采取以下策略:
- 1、在Application的構(gòu)造器方法、attachBaseContext()、onCreate()方法中不要進(jìn)行耗時(shí)操作的初始化,一些數(shù)據(jù)預(yù)取放在異步線程中,可以采取Callable實(shí)現(xiàn)。
- 2、對(duì)于sp的初始化,因?yàn)閟p的特性在初始化時(shí)候會(huì)對(duì)數(shù)據(jù)全部讀出來(lái)存在內(nèi)存中,所以這個(gè)初始化放在主線程中不合適,反而會(huì)延遲應(yīng)用的啟動(dòng)速度,對(duì)于這個(gè)還是需要放在異步線程中處理。
- 3、對(duì)于MainActivity,由于在獲取到第一幀前,需要對(duì)contentView進(jìn)行測(cè)量布局繪制操作,盡量減少布局的層次,考慮StubView的延遲加載策略,當(dāng)然在onCreate、onStart、onResume方法中避免做耗時(shí)操作。
遵循上面三種策略可明顯提高app啟動(dòng)速度。
優(yōu)化應(yīng)用啟動(dòng)時(shí)的體驗(yàn)
對(duì)于應(yīng)用的啟動(dòng)時(shí)間,只能是盡量的避免一些耗時(shí)的、非必要的操作在主線程中,這樣相對(duì)可以縮減一部分啟動(dòng)的耗時(shí),另外一方面在等待第一幀顯示的時(shí)間里,可以加入一些配置以增加體驗(yàn),比如加入Activity的background,這個(gè)背景會(huì)在顯示第一幀前提前顯示在界面上。
1、先為主界面單獨(dú)寫(xiě)一個(gè)主題style,設(shè)置一張待顯示的圖片,這里我設(shè)置了一個(gè)顏色,然后在manifest中設(shè)置給MainActivity:
<style name="AppTheme.Launcher">
<item name="android:windowBackground">@drawable/bule</item>
</style>
//...
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.Launcher">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
2、然后在MainActivity中加載布局前把AppTheme重新設(shè)置給MainActivity:
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
這樣在啟動(dòng)時(shí)會(huì)先顯示background,然后待界面繪制完成再顯示主界面:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家學(xué)習(xí)Android軟件編程有所幫助。
- 淺談android性能優(yōu)化之啟動(dòng)過(guò)程(冷啟動(dòng)和熱啟動(dòng))
- Android啟動(dòng)畫(huà)面的實(shí)現(xiàn)方法
- Android開(kāi)發(fā)之設(shè)置開(kāi)機(jī)自動(dòng)啟動(dòng)的幾種方法
- Android優(yōu)化之啟動(dòng)頁(yè)去黑屏實(shí)現(xiàn)秒啟動(dòng)
- Android APP啟動(dòng)方式、啟動(dòng)流程及啟動(dòng)優(yōu)化分析
- Android實(shí)戰(zhàn)APP啟動(dòng)速度優(yōu)化
- Android 優(yōu)化之a(chǎn)pp啟動(dòng)優(yōu)化的實(shí)現(xiàn)
- 一分鐘快速定位Android啟動(dòng)耗時(shí)問(wèn)題
相關(guān)文章
詳談Android中onTouch與onClick事件的關(guān)系(必看)
下面小編就為大家?guī)?lái)一篇詳談Android中onTouch與onClick事件的關(guān)系(必看)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03
Android RecyclerView設(shè)置下拉刷新的實(shí)現(xiàn)方法
這篇文章主要介紹了Android RecyclerView設(shè)置下拉刷新的實(shí)現(xiàn)方法,希望通過(guò)本文通過(guò)SwipeRefreshLayout方式實(shí)現(xiàn)下拉刷新,需要的朋友可以參考下2017-10-10
Android仿考拉全局滑動(dòng)返回及聯(lián)動(dòng)效果的實(shí)現(xiàn)方法
這篇文章主要給大家介紹了關(guān)于Android仿考拉全局滑動(dòng)返回及聯(lián)動(dòng)效果的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-08-08
在Android應(yīng)用中實(shí)現(xiàn)離線數(shù)據(jù)同步的步驟詳解
在構(gòu)建 Android 應(yīng)用時(shí),離線數(shù)據(jù)同步是一個(gè)不可或缺的環(huán)節(jié),無(wú)論是網(wǎng)絡(luò)狀況不佳,還是用戶(hù)處于飛行模式,離線數(shù)據(jù)同步都能讓用戶(hù)在無(wú)網(wǎng)絡(luò)的情況下繼續(xù)使用應(yīng)用,本文將詳細(xì)介紹如何在 Android 應(yīng)用中實(shí)現(xiàn)離線數(shù)據(jù)同步,需要的朋友可以參考下2024-08-08
詳解Activity之singletast啟動(dòng)模式及如何使用intent傳值
在一個(gè)新棧中創(chuàng)建該Activity實(shí)例,并讓多個(gè)應(yīng)用共享改棧中的該Activity實(shí)例。一旦改模式的Activity的實(shí)例存在于某個(gè)棧中,任何應(yīng)用再激活改Activity時(shí)都會(huì)重用該棧中的實(shí)例,其效果相當(dāng)于多個(gè)應(yīng)用程序共享一個(gè)應(yīng)用,不管誰(shuí)激活該Activity都會(huì)進(jìn)入同一個(gè)應(yīng)用中2015-11-11
Android實(shí)現(xiàn)帶頭像的用戶(hù)注冊(cè)頁(yè)面
這篇文章主要介紹了Android實(shí)現(xiàn)帶頭像的用戶(hù)注冊(cè)頁(yè)面的相關(guān)資料,介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06

