Android啟動(dòng)優(yōu)化

1. 概述

Android的啟動(dòng)優(yōu)化主要是加速用戶(hù)打開(kāi)App到可交互的時(shí)間。在這段時(shí)間里面經(jīng)歷的Application的啟動(dòng)創(chuàng)建,SplashActivity、MainActivity的啟動(dòng)創(chuàng)建(有些App沒(méi)有Splash頁(yè)面)。

  • Application的創(chuàng)建過(guò)程的調(diào)用順序大致如下:
  • Activity的創(chuàng)建到第一幀顯示過(guò)程調(diào)用順序如下:

從視覺(jué)交互來(lái)說(shuō),App的啟動(dòng)過(guò)程主要顯示了3屏:

  • 第一屏:在主題中設(shè)置android:windowBackground的圖片,這個(gè)過(guò)程在Application.attachBaseContext()——Splash.onWindowFocusChanged()之間。
  • 第二屏:Splash繪制的內(nèi)容,這個(gè)過(guò)程在Splash.onWindowFocusChanged()——Main.onWindowFocusChanged()之間。
  • 第三屏:Main繪制的內(nèi)容,這個(gè)在Main.onWindowFocusChanged之后。

所以,啟動(dòng)的優(yōu)化范圍一般在Application. attachBaseContext ()——Main.onWindowFocusChanged()之間。其中第一屏和第二屏是的耗時(shí)是需要重點(diǎn)關(guān)注。這里把第一屏的時(shí)間叫做Application的啟動(dòng)耗時(shí),第一屏+第二屏的時(shí)間Application啟動(dòng)到可交互頁(yè)面的啟動(dòng)耗時(shí)。

2. 啟動(dòng)優(yōu)化步驟

2.1 評(píng)估時(shí)間數(shù)據(jù)

在啟動(dòng)優(yōu)化中,并不是自己覺(jué)得哪個(gè)地方會(huì)耗時(shí),就開(kāi)始做優(yōu)化,這樣可能帶來(lái)辛辛苦苦做了一頓優(yōu)化后,總耗時(shí)還是沒(méi)有好的效果,原因可能是我們直覺(jué)耗時(shí)的地方并不準(zhǔn)確。正確的做法是先得到啟動(dòng)過(guò)程中每個(gè)方法的時(shí)間,得到全部時(shí)間表后,分析耗時(shí)的地方在哪里記錄下來(lái)。
那怎么獲取到每個(gè)方法的執(zhí)行時(shí)間呢?,大致如下:
1. 自帶的Profiler
配置應(yīng)用啟動(dòng)時(shí)開(kāi)始profiler監(jiān)控如下:

  1. Looper
    在之前的文章Android卡頓監(jiān)控中有對(duì)其的具體實(shí)現(xiàn)。

  2. Systrace+函數(shù)插樁

2.2 梳理業(yè)務(wù)

在第一步得到時(shí)間數(shù)據(jù)后,下一步就是整理啟動(dòng)過(guò)程的業(yè)務(wù)梳理,避免因優(yōu)化而影響業(yè)務(wù)。

2.3 優(yōu)化業(yè)務(wù)

優(yōu)化的思想大致如下:

  1. 通過(guò)上面的兩個(gè)步驟,看主線(xiàn)程究竟慢哪里
  2. 懶加載,包括業(yè)務(wù)與布局的懶加載
  3. 拋到子線(xiàn)程讓其自己加載
  4. 提前加載,通過(guò)多線(xiàn)程提高效率
  5. 檢查主線(xiàn)程的IO操作
  6. 控制線(xiàn)程的數(shù)量和GC的次數(shù)

1. Application.onCreate()
在這個(gè)方法中主要是做SDK的初始化和App狀態(tài)判斷,
sdk優(yōu)化主要有三點(diǎn):
一:sdk的懶加載,再使用到的時(shí)候才去初始化,不要全部放到在Application初始化。
二:對(duì)于sdk有依賴(lài)的關(guān)系的,比如sdk2需要sdk1完成加載后開(kāi)始初始化,可以利用拓?fù)渌惴▋?yōu)化實(shí)現(xiàn)sdk加載:android-startup
三:把sdk放到子線(xiàn)程中自己初始化,不要阻塞主線(xiàn)程的時(shí)間,一些必須初始化的sdk,可以通過(guò)多線(xiàn)程加載然后通過(guò)CountDownLatch進(jìn)行阻塞和喚醒。

業(yè)務(wù)代碼的優(yōu)化:
一:盡量不要濫用ContentProvider,因?yàn)槠涫窃贏pplication.attachBaseContext就會(huì)初始化其ContentProvider.onCreate()方法,會(huì)加長(zhǎng)啟動(dòng)時(shí)間。
二:查看Application主線(xiàn)程耗時(shí)的地方,盡量去優(yōu)化。

2. Activity.onCreate()
要弄清楚哪里耗時(shí)了,才著手優(yōu)化。常見(jiàn)優(yōu)化有:
一: setContentVIew()的耗時(shí),這時(shí)要優(yōu)化布局,減少布局背景的重復(fù)渲染、減少層級(jí)、對(duì)于不一定顯示的布局用ViewStub按需加載。子線(xiàn)程加載布局,或提前子線(xiàn)程加載。
二:initView()初始化View時(shí)不要做耗時(shí)操作,比如一些IO操作、播放器等做到按需懶加載,也可以通過(guò)讓其在多線(xiàn)程中加載不阻塞主線(xiàn)程,也可以通過(guò)多線(xiàn)程提前加載。
三:主頁(yè)面的ViewPager+Fragment可以通過(guò)懶加載按需加載Fragment

3. Activity.onResume()
不要在onResume()方法中不要做主線(xiàn)程耗時(shí)操作,因?yàn)檫@時(shí)頁(yè)面還沒(méi)渲染出來(lái),其還要通過(guò)Vsync信號(hào)來(lái)臨做繪制三大流程,最終交給屏幕渲染出來(lái),回調(diào)執(zhí)行onWindowFocusChanged()方法。

4.檢查主線(xiàn)程IO操作
可以在線(xiàn)下通過(guò)StrictMode類(lèi)來(lái)檢查IO操作,如果在主線(xiàn)程有IO操作會(huì)輸入日志。

   private fun startStrictMode() {
        if (BuildConfig.DEBUG) {
            StrictMode.setThreadPolicy(
                StrictMode.ThreadPolicy.Builder()
                    .detectDiskWrites()
                    .detectDiskReads()
                    .detectNetwork()
                    .penaltyLog()
                    .build()
            )

            StrictMode.setVmPolicy(
                StrictMode.VmPolicy.Builder()
                    .detectLeakedClosableObjects()
                    .penaltyLog()
                    .build()
            )

        }
    }

總結(jié)

Android啟動(dòng)優(yōu)化更多的是一種優(yōu)化思路,因?yàn)槊總€(gè)項(xiàng)目都不一樣,導(dǎo)致優(yōu)化的點(diǎn)也不一樣,但掌握了優(yōu)化思路可以以不變應(yīng)萬(wàn)變。

  1. 首先分析啟動(dòng)耗時(shí)的地方和啟動(dòng)過(guò)程相關(guān)任務(wù)。
  2. 知道主線(xiàn)程哪里耗時(shí)
  3. SDK初始化按需加載、有依賴(lài)關(guān)系通過(guò)拓?fù)渌惴▋?yōu)化
  4. 布局優(yōu)化,子線(xiàn)程加載布局,提前加載布局
  5. 一些主線(xiàn)程耗時(shí)的任務(wù)要么提前子線(xiàn)程加載,要么用到的時(shí)候才加載。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容