1. 程式人生 > >AndroidAPP啟動速度優化解析;冷啟動和熱啟動

AndroidAPP啟動速度優化解析;冷啟動和熱啟動

啟動方式

通常來說,在安卓中應用的啟動方式分為兩種:冷啟動和熱啟動。

1、冷啟動:當啟動應用時。後臺沒有該應用的程序,這時系統會又一次建立一個新的程序分配給該應用,這個啟動方式就是冷啟動。

2、熱啟動:當啟動應用時,後臺已有該應用的程序(例:按back鍵、home鍵,應用盡管會退出,可是該應用的程序是依舊會保留在後臺,可進入任務列表檢視)。所以在已有程序的情況下。這樣的啟動會從已有的程序中來啟動應用。這個方式叫熱啟動。

特點

1、冷啟動:冷啟動由於系統會又一次建立一個新的程序分配給它。所以會先建立和初始化Application類,再建立和初始化MainActivity類(包含一系列的測量、佈局、繪製),最後顯示在介面上。

2、熱啟動:熱啟動由於會從已有的程序中來啟動,所以熱啟動就不會走Application這步了,而是直接走MainActivity(包含一系列的測量、佈局、繪製)。所以熱啟動的過程僅僅須要建立和初始化一個MainActivity即可了。而不必建立和初始化Application,由於一個應用從新程序的建立到程序的銷燬。Application僅僅會初始化一次。

上面說的啟動是點選app的啟動圖示來啟動的。而第二種方式是進入近期使用的列表介面來啟動應用,這樣的不應該叫啟動,應該叫恢復。

應用啟動的流程

在安卓系統上,應用在沒有程序的情況下,應用的啟動都是這樣一個流程:當點選app的啟動圖示時。安卓系統會從Zygote程序中fork創建出一個新的程序分配給該應用。之後會依次建立和初始化Application類、建立MainActivity類、載入主題樣式Theme中的windowBackground等屬性設定給MainActivity以及配置Activity層級上的一些屬性、再inflate佈局、當onCreate/onStart/onResume方法都走完了後最後才進行contentView的measure/layout/draw顯示在介面上,所以直到這裡,應用的第一次啟動才算完畢,這時候我們看到的介面也就是所說的第一幀。

所以,總結一下,應用的啟動流程例如以下:

Application的構造器方法——>attachBaseContext()——>onCreate()——>Activity的構造方法——>onCreate()——>配置主題中背景等屬性——>onStart()——>onResume()——>測量佈局繪製顯示在介面上。

測量應用啟動的時間

在上面這個啟動流程中,不論什麼一個地方有耗時操作都會拖慢我們應用的啟動速度,而應用啟動時間是用毫秒度量的。對於毫秒級別的快慢度量我們還是須要去精確的測量到究竟應用啟動花了多少時間。而依據這個時間來做衡量。

什麼才是應用的啟動時間

從點選應用的啟動圖示開始創建出一個新的程序直到我們看到了介面的第一幀,這段時間就是應用的啟動時間。

我們要測量的也就是這段時間。測量這段時間能夠通過adb shell命令的方式進行測量,這樣的方法測量的最為精確。命令為:

adb shell am start -W [packageName]/[packageName.MainActivity]

執行成功後將返回三個測量到的時間:
1、ThisTime:一般和TotalTime時間一樣。除非在應用啟動時開了一個透明的Activity預先處理一些事再顯示出主Activity,這樣將比TotalTime小。
2、TotalTime:應用的啟動時間。包含建立程序+Application初始化+Activity初始化到介面顯示。

3、WaitTime:一般比TotalTime大點,包含系統影響的耗時。

以下是測量一個應用冷啟動和熱啟動的時間:
冷啟動:

 

熱啟動:

 

能夠看到在程序已經存在的情況下。僅僅須要又一次初始化MainActivity。這樣的啟動比較快。只是大多數情況下應用的啟動都是冷啟動。由於使用者都會在任務列表中手動關閉遺留的應用程序。

降低應用啟動時的耗時

針對冷啟動時候的一些耗時,如上測得這個應用算是中型的app,在冷啟動的時候耗時已經快700ms了,假設專案再大點在Application中配置了很多其它的初始化操作,這樣將可能達到1s,這樣每次啟動都明顯感覺延遲。所以在進行應用初始化的時候採取以下策略:
1、在Application的構造器方法、attachBaseContext()、onCreate()方法中不要進行耗時操作的初始化,一些資料預取放在非同步執行緒中,能夠採取Callable實現。
2、對於sp的初始化,由於sp的特性在初始化時候會對資料所有讀出來存在記憶體中,所以這個初始化放在主執行緒中不合適,反而會延遲應用的啟動速度,對於這個還是須要放在非同步執行緒中處理。

3、對於MainActivity,由於在獲取到第一幀前。須要對contentView進行測量佈局繪製操作,儘量降低佈局的層次。考慮StubView的延遲載入策略。當然在onCreate、onStart、onResume方法中避免做耗時操作。

遵循上面三種策略可明顯提高app啟動速度。

優化應用啟動時的體驗

對於應用的啟動時間,僅僅能是儘量的避免一些耗時的、非必要的操作在主執行緒中,這樣相對能夠縮減一部分啟動的耗時,另外一方面在等待第一幀顯示的時間裡,能夠增加一些配置以增加體驗,比方增加Activity的background,這個背景會在顯示第一幀前提前顯示在介面上。

1、先為主介面單獨寫一個主題style,設定一張待顯示的圖片,這裡我設定了一個顏色,然後在manifest中設定給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又一次設定給MainActivity:

@Override
    protected void onCreate(Bundle savedInstanceState) {

        setTheme(R.style.AppTheme);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
}        

這樣在啟動時會先顯示background,然後待介面繪製完畢再顯示主介面

 

最後歡迎加入Android進階交流群;964557053。進群可免費領取一份最新技術大綱和Android進階資料。請備註csdn