天天看點

Android APP啟動優化一 APP啟動測量1 前言2 APP啟動類别3 APP啟動測量

1 前言

Android APP 啟動優化是性能優化的重要方向之一,特别是對于原生應用來講,控制在1s内以内對一個APP的競争力很重要,下面從幾個角度來講APP的啟動優化,先看APP的啟動類别

2 APP啟動類别

參考google官方文檔App startup time,官方對APP啟動主要做了三種分類

1.冷啟動

冷啟動指的是APP從頭開始啟動,沒有建立程序,需要完整的走程序建立,ActivityThread建立,Application建立等生命周期的啟動,冷啟動耗時最多

啟動時分為以下幾步

1 加載和啟動app

2 加載空白window

3 建立App程序

随後進行如下步驟

1 建立Application對象,并回調其方法

2 啟動主線程

3 建立MainActivity

4 初始化View和加載布局

5 布局螢幕

6 首幀繪制

冷啟動一般流程如下:

Android APP啟動優化一 APP啟動測量1 前言2 APP啟動類别3 APP啟動測量

2.暖啟動

當應用中的Activity被銷毀,但在記憶體中常駐時,應用的啟動方式就會變為暖啟動。相比冷啟動,暖啟動過程減少了對象初始化、布局加載等工作,啟動時間更短。但啟動時,系統依然會展示一個空白背景,直到第一個Activity的内容呈現為止。是以暖啟動一般會走Activity的onCreate生命周期,暖啟動耗時較少,一般需要注意在Activity的生命周期中不要做耗時操作即可。

3.熱啟動

相比暖啟動,熱啟動時應用做的工作更少,啟動時間更短。熱啟動産生的場景很多,常見如:使用者使用傳回鍵退出應用,然後馬上又重新啟動應用。熱啟動較快,一般需要注意在onResmue中不要做耗時操作

對于系統流程我們一般無法改變,是以對于三方應用來說,APP啟動優化的主要方向在Application的生命周期和Activity的生命周期中

3 APP啟動測量

前面講了APP啟動的類别,現在要講如何粗略或者詳細的測量一個APP的啟動時間,一般來說有以下幾種辦法

1 adb 指令測量

adb shell am start –W packageName/首屏Activity

例如:

adb shell am start –W com.qiyei.mall/com.qiyei.mall.ui.activity. MainActivity
           

執行如下:

Android APP啟動優化一 APP啟動測量1 前言2 APP啟動類别3 APP啟動測量

MainActivity 是首頁,HomeActivity是首頁

ThisTime: 最後一個Activity啟動耗時

TotalTime: 啟動所有Activity耗時

WaitTime: AMS啟動Activity耗時

2 ActivityManager中日志列印

ActivityManager中會列印啟動activity的時間

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms (total +1m22s643ms)
           

相關的代碼如下:

ActivityRecord#reportLaunchTimeLocked()

private void reportLaunchTimeLocked(final long curTime) {
        final ActivityStack stack = getStack();
        if (stack == null) {
            return;
        }
        final long thisTime = curTime - displayStartTime;
        final long totalTime = stack.mLaunchStartTime != 0
                ? (curTime - stack.mLaunchStartTime) : thisTime;
        if (SHOW_ACTIVITY_START_TIME) {
            Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER, "launching: " + packageName, 0);
            EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
                    userId, System.identityHashCode(this), shortComponentName,
                    thisTime, totalTime);
            StringBuilder sb = service.mStringBuilder;
            sb.setLength(0);
            sb.append("Displayed ");
            sb.append(shortComponentName);
            sb.append(": ");
            TimeUtils.formatDuration(thisTime, sb);
            if (thisTime != totalTime) {
                sb.append(" (total ");
                TimeUtils.formatDuration(totalTime, sb);
                sb.append(")");
            }
            Log.i(TAG, sb.toString());
        }
        mStackSupervisor.reportActivityLaunchedLocked(false, this, thisTime, totalTime);
        if (totalTime > 0) {
            //service.mUsageStatsService.noteLaunchTime(realActivity, (int)totalTime);
        }
        displayStartTime = 0;
        stack.mLaunchStartTime = 0;
    }
           

可以看到列印的是,這個時間從應用啟動(建立程序)開始計算,到完成視圖的第一次繪制的時間

3 手動打點

這個思想也比較簡單,由于應用層能接觸到的最早方法是Application#attachBaseContext()而結束時間,我們可以認為是Activity#onWindowFocusChanged或者View的真正繪制完成,是以我們可以在attachBaseContext記錄一下時間,在onWindowFocusChanged中或者View繪制完成後記錄結束時間,隻是需要注意怎麼處理View的onDraw監聽問題

4 Systrace測量

這個可以參考官方文章systrace來進行操作,注意systrace需要python環境,是以需要先搭建好python環境。下面是一個systrace的例子

Android APP啟動優化一 APP啟動測量1 前言2 APP啟動類别3 APP啟動測量

可以看到,systrace可以看到更多的系統調用過程,例如這裡可以看到程序Zygote建立和ActivityThread的初始化時間等,有助于分析啟動時當時系統的狀态。

這一篇就介紹到這,下一篇會介紹TraceView和Systrace的簡單使用