性能優(yōu)化(四):Android啟動(dòng)速度優(yōu)化

1.App啟動(dòng)流程
app啟動(dòng)流程.jpg
  1. 點(diǎn)擊桌面App圖標(biāo)供置,Launcher進(jìn)程采用Binder IPC向system_server進(jìn)程發(fā)起startActivity請(qǐng)求谨湘。
  2. system_server進(jìn)程接收到請(qǐng)求后,向Zygote進(jìn)程發(fā)送創(chuàng)建進(jìn)程的請(qǐng)求芥丧。
  3. Zygote進(jìn)程fork出新的子進(jìn)程紧阔,即App進(jìn)程
  4. App進(jìn)程通過(guò)Binder IPC向system_server進(jìn)程發(fā)起attach Application請(qǐng)求
  5. system_server進(jìn)程收到請(qǐng)求后,進(jìn)行一系列準(zhǔn)備工作后续担,再通過(guò)Binder IPC向App進(jìn)程發(fā)送scheduleLaunchActivity請(qǐng)求擅耽。
  6. App進(jìn)程的binder線程(ApplicationThread)在收到請(qǐng)求后,通過(guò)handler向主線程發(fā)送LAUNCHER_ACTIVITY消息物遇。
  7. 主線程收到Message后乖仇,通過(guò)反射機(jī)制創(chuàng)建目標(biāo)Activity,并回調(diào)Activity.onCreate()等方法询兴。
  8. 到此乃沙,App便正式啟動(dòng),開始進(jìn)入Activity生命周期蕉朵,執(zhí)行完onCreate/onStart/onResume方法崔涂,UI渲染結(jié)束后便可以看到App的主界面。
2.啟動(dòng)狀態(tài)

應(yīng)用有三種啟動(dòng)狀態(tài)始衅,每種狀態(tài)都會(huì)影響應(yīng)用向用戶顯示所需要的時(shí)間:

  • 冷啟動(dòng)
    系統(tǒng)不存在App進(jìn)程(App首次啟動(dòng)或App被完全殺死)時(shí)啟動(dòng)App

    • 第一階段
      1冷蚂、加載并啟動(dòng)app
      2、啟動(dòng)后立即顯示一個(gè)空白的啟動(dòng)窗口
      3汛闸、創(chuàng)建app進(jìn)程
    • 第二階段
      1蝙茶、創(chuàng)建app對(duì)象
      2、啟動(dòng)主線程
      3诸老、創(chuàng)建主Activity
      4隆夯、加載布局
      5、布置屏幕
      6别伏、首幀繪制
  • 熱啟動(dòng)
    當(dāng)我們按下Home鍵或其它情況app被切換到后臺(tái)蹄衷,再次啟動(dòng)app的過(guò)程。

    熱啟動(dòng)時(shí)厘肮,系統(tǒng)將activity帶回前臺(tái)愧口,如果應(yīng)用程序的所有activity仍駐留在內(nèi)存中,應(yīng)用不必重復(fù)執(zhí)行對(duì)象初始化类茂、布局加載和繪制耍属。

  • 溫啟動(dòng)
    溫啟動(dòng)包含了冷啟動(dòng)的一些操作托嚣,由于app進(jìn)程依然在,溫啟動(dòng)只執(zhí)行冷啟動(dòng)的第二階段厚骗,這代表中它比熱啟動(dòng)有更多的開銷示启。如:用戶按返回鍵退出應(yīng)用,然后又重新啟動(dòng)它领舰;系統(tǒng)回收了app的內(nèi)存夫嗓,然后重新啟動(dòng)app。

3.冷啟動(dòng)耗時(shí)統(tǒng)計(jì)

性能測(cè)試中存在2-5-8原則:2s內(nèi)很快提揍,2~5s 還可以啤月,5~8s 很慢還可以接受,8s糟糕透了劳跃。

Google 提出一項(xiàng)計(jì)劃Android Vitals:冷啟動(dòng)5s內(nèi),溫啟動(dòng)2s內(nèi)浙垫,熱啟動(dòng)1.5s內(nèi)刨仑。

  • 系統(tǒng)日志統(tǒng)計(jì)
    Android Studio Logcat包含一行輸出,名為Displayed的值夹姥,表示從啟動(dòng)進(jìn)程到屏幕上完成對(duì)應(yīng)Activity繪制所用的時(shí)間杉武。

    ActivityTaskManager: Displayed com.azxc.easyworkapp.test/com.azxc.easyworkapp.ui.LoginActivity: +1s78ms
    
  • adb命令統(tǒng)計(jì)
    adb shell am start -S -W [packageName]/[activityName]

    adb命令統(tǒng)計(jì)啟動(dòng)耗時(shí).png

4.CPU Profile

我們可以通過(guò)CPU Profiler查看應(yīng)用在某段時(shí)間里某個(gè)線程執(zhí)行了哪些方法,并且還定量的展示了執(zhí)行這些方法所耗費(fèi)的時(shí)間及其方法的調(diào)用堆棧辙售。
cpu profile.png

CPU Profile只支持Android 8.0以上轻抱,其它版本可以用Debug API生成trace

public class MyApplication extends Application {
    public MyApplication(){
        //開始跟蹤
        Debug.startMethodTracing("trace");
    }
    //...
}

public class MainActivity extends AppCompatActivity{
    @Override
    public void onWindowFocusChanged(booleanhasFocus){
        super.onWindowFocusChanged(hasFocus);
        //停止跟蹤
        Debug.stopMethodTracing();    
    }
    //...
}

運(yùn)行app會(huì)生成.trace文件,用Android Studio打開即可旦部。

5.StrictMode

嚴(yán)苛模式是一個(gè)開發(fā)工具祈搜,能夠檢測(cè)程序中的違例,從而修復(fù)士八。最常用于主線程中磁盤讀寫和網(wǎng)絡(luò)訪問(wèn)容燕。

public class MyApplication extends Application {
     public void onCreate() {
     if (BuildConfig.DEBUG) {
         //線程檢查策略
         StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                 .detectDiskReads() //讀磁盤
                 .detectDiskWrites()//寫磁盤
                 .detectNetwork()   //檢查網(wǎng)絡(luò)
                 .penaltyLog()
                 .build());
         //VM檢查策略
         StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                 .detectLeakedSqlLiteObjects()  //Sqlite對(duì)象,如cursors
                 .detectLeakedClosableObjects() //未關(guān)閉的Closeable對(duì)象
                 .penaltyLog()  //違規(guī)打印日志
                 .penaltyDeath() //違規(guī)崩潰
                 .build());
     }
     super.onCreate();
 }
    //...
}

檢測(cè)項(xiàng)

  • ThreadPolicy
    • detectAll 檢測(cè)所有潛在的違例
    • detectCustomSlowCalls 自定義耗時(shí)操作
    • detectDiskReads 讀磁盤
    • detectDiskWrites 寫磁盤
    • detectNetwork 檢查網(wǎng)絡(luò)
    • detectResourceMismatches 檢查資源類型是否匹配
  • VmPolicy
    • detectAll 檢測(cè)所有潛在的
    • detectActivityLeaks 檢測(cè)Activity的泄露
    • detectCleartextNetwork 檢測(cè)明文的網(wǎng)絡(luò)
    • detectFileUriExposure 檢測(cè)file://或者是content://
    • detectLeakedClosableObjects 檢查為管理的Closable對(duì)象
    • detectLeakedRegistrationObjects 檢測(cè)需要注冊(cè)類型是否解注
    • detectLeakedSqlLiteObjects 檢測(cè)sqlite對(duì)象婚度,如cursors

檢測(cè)到違規(guī)項(xiàng)之后的表現(xiàn)形式

  • penaltyDeath crash蘸秘,在所有表現(xiàn)形式最后運(yùn)行,
  • penaltyDeathOnNetwork crash,在所有值錢蝗茁,必須調(diào)用detectNetwork去允許這個(gè)醋虏。
  • penaltyDialog 彈出dialog
  • penaltyDropBox 將日志吸入到dropbox中
  • penaltyFlashScreen 屏幕閃爍
  • penaltyLog log日志
6.啟動(dòng)優(yōu)化相關(guān)

1.異步加載:耗時(shí)多的加載放到子線程中異步執(zhí)行
2.延遲加載: 非必須的數(shù)據(jù)延遲加載

Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
        @Override
        public boolean queueIdle() {
            XXX.init();
            return false;
        }
});

3.提前加載:利用ContentProvider提前進(jìn)行初始化

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市哮翘,隨后出現(xiàn)的幾起案子颈嚼,更是在濱河造成了極大的恐慌,老刑警劉巖忍坷,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粘舟,死亡現(xiàn)場(chǎng)離奇詭異熔脂,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)柑肴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門霞揉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人晰骑,你說(shuō)我怎么就攤上這事适秩。” “怎么了硕舆?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵秽荞,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我抚官,道長(zhǎng)扬跋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任凌节,我火速辦了婚禮钦听,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘倍奢。我一直安慰自己朴上,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布卒煞。 她就那樣靜靜地躺著痪宰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪畔裕。 梳的紋絲不亂的頭發(fā)上衣撬,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天,我揣著相機(jī)與錄音柴钻,去河邊找鬼淮韭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛贴届,可吹牛的內(nèi)容都是我干的靠粪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼毫蚓,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼占键!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起元潘,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤畔乙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后翩概,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體牲距,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡返咱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了牍鞠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咖摹。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖难述,靈堂內(nèi)的尸體忽然破棺而出萤晴,到底是詐尸還是另有隱情,我是刑警寧澤胁后,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布店读,位于F島的核電站,受9級(jí)特大地震影響攀芯,放射性物質(zhì)發(fā)生泄漏屯断。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一敲才、第九天 我趴在偏房一處隱蔽的房頂上張望裹纳。 院中可真熱鬧,春花似錦紧武、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至已添,卻和暖如春妥箕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背更舞。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工畦幢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缆蝉。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓宇葱,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親刊头。 傳聞我的和親對(duì)象是個(gè)殘疾皇子黍瞧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容