溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

啟動優(yōu)化的方法有哪些

發(fā)布時間:2021-10-21 16:10:50 來源:億速云 閱讀:183 作者:iii 欄目:編程語言

這篇文章主要介紹“啟動優(yōu)化的方法有哪些”,在日常操作中,相信很多人在啟動優(yōu)化的方法有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”啟動優(yōu)化的方法有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

冷啟動、溫啟動、熱啟動

首先了解下啟動的這三個概念,也是面試常被問到的:

  • 冷啟動。冷啟動指的是該應用程序在此之前沒有被創(chuàng)建,發(fā)生在應用程序首次啟動或者自上次被終止后的再次啟動。簡單的說就是app進程還沒有,需要創(chuàng)建app的進程并啟動app。

比如開機后,點擊屏幕的app圖標啟動應用。

冷啟動的過程主要分為兩步:

1)系統(tǒng)任務。加載并啟動應用程序;顯示應用程序的空白啟動窗口;創(chuàng)建APP進程 

2)APP進程任務。啟動主線程;創(chuàng)建Activity;加載布局;屏幕布局;繪制屏幕

其實這不就是APP的啟動流程嘛?所以冷啟動是會完整走完一個啟動流程的,從系統(tǒng)到進程。

  • 溫啟動。溫啟動指的是App進程存在,但Activity可能因為內(nèi)存不足被回收,這時候啟動App不需要重新創(chuàng)建進程,只需要執(zhí)行APP進程中的一些任務,比如創(chuàng)建Activity。

比如返回Home后,又繼續(xù)使用其他的APP,時間久了或者打開的應用多了,之前應用的Activity有可能被回收了,但是進程還在。

所以溫啟動過程相當于執(zhí)行了冷啟動的第二過程,也就是APP進程任務,需要重新啟動線程,Activity等。

  • 熱啟動。熱啟動就是指App進程存在,并且Activity對象仍然存在內(nèi)存中沒有被回收。

比如app被切到后臺,再次啟動app的過程。

所以熱啟動的開銷最少,這個過程只會把Activity從后臺展示到前臺,無需初始化,布局繪制等工作。 

優(yōu)化點

三種啟動方式中,冷啟動經(jīng)歷的時間最長,也是走完了最完整的啟動流程,所以我們再次分析下冷啟動的啟動流程,看看有哪些可以優(yōu)化的點:

  • Launcher startActivity
  • AMS startActivity
  • Zygote fork 進程
  • ActivityThread main()
  • ActivityThread attach
  • handleBindApplication
  • attachBaseContext
  • Application attach
  • installContentProviders
  • Application onCreate
  • Looper.loop
  • Activity onCreate,onResume

縱觀整個流程,其實我們能動的地方不多,無非就是Application的attach,onCreate方法,Activity的onCreate,onResume方法,這些方法也就是我們的優(yōu)化點。 

優(yōu)化方案 

1)消除啟動時的白屏/黑屏

App啟動的時候會有一個白屏/黑屏時間,我們可以通過設置windowBackground屬性來給啟動的Activity提供一個drawable,這樣就給用戶一個快遞啟動的假象了。

<activity ...
android:theme="@style/MyAppTheme" />

<style name="MyAppTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="android:windowBackground">@drawable/logo</item> 
</style>
  

2)第三方庫懶加載/異步加載

ApplicationonCreate方法中,總會有很多初始化操作,比如友盟,數(shù)據(jù)庫,網(wǎng)絡請求庫,廣告SDK等等。

對此,我們能做的有哪些呢?

  • 異步加載。有些庫不需要在主線程進行初始化,那么我們就可以在子線程中進行初始化,進行異步加載。
  • 延遲加載。有些庫不必要一開始就初始化,我們可以按需初始化,將一些庫放到用它的時候再初始化,或者放到啟動頁去進行初始化。

所以需要我們對這些初始化操作進行分析,哪些需要在主線程進行,哪些可以延遲加載,哪些初始化任務有先后關(guān)系等等。這里涉及到一個啟動器的概念,啟動器的用處就是可以充分利用CPU多核,自動梳理任務順序。有空的朋友可以去了解下。

這里還需要注意一點就是線程的使用:

  • 即不要頻繁創(chuàng)建線程,線程的頻繁創(chuàng)建是耗性能的,所以需要用到     線程池去執(zhí)行異步任務。 

3)預創(chuàng)建Activity

Java中的對象第一次創(chuàng)建的時候,java虛擬機首先檢查類對應的Class對象是否已經(jīng)加載。如果沒有加載,jvm會根據(jù)類名查找.class文件,將其Class對象載入。同一個類第二次new的時候就不需要加載類對象,而是直接實例化,創(chuàng)建時間就縮短了。

今日頭條中就有這種做法,先創(chuàng)建一個Activity的實例。 

4)預加載數(shù)據(jù)

在我們的啟動頁或者主頁可以將一些要用到的數(shù)據(jù)保存到內(nèi)存或者數(shù)據(jù)庫,那么其他頁面要用到這些數(shù)據(jù)的時候就可以直接使用并顯示了。 

5)Multidex預加載優(yōu)化

由于65536方法限制,所以一般class文件要生成多個dex文件,Android5.0以下,ClassLoader加載類的時候只會從class.dex(主dex)里加載,所以要執(zhí)行MultiDex.install(context)方法才能正常讀取所有的dex類。

而這個install方法就是耗時大戶,會解壓apk,遍歷dex文件,壓縮dex、將dex文件通過反射轉(zhuǎn)換成DexFile對象、反射替換數(shù)組。

這里需要的方案就是今日頭條方案:

  • 在Application的attachBaseContext方法里,啟動另一個進程的LoadDexActivity去異步執(zhí)行MultiDex邏輯,顯示Loading。

  • 然后主進程Application進入while循環(huán),不斷檢測MultiDex操作是否完成 ,MultiDex執(zhí)行完之后主進程Application繼續(xù)執(zhí)行ContentProvider初始化和Application onCreate方法,也就是主進程正常的邏輯。

所以重點就是單開進程去執(zhí)行MultiDex邏輯,這樣就不影響APP的啟動了。

當然,這僅僅針對5.0以下加載Multidex情況,5.0以上默認使用ART加載類,安裝時候就已經(jīng)轉(zhuǎn)換dex文件為oat文件了,所以無需優(yōu)化Multidex情況了。 

6)Webview啟動優(yōu)化

如果我們的主頁涉及到Webview,那我們還要處理WebView的優(yōu)化。因為Webview的創(chuàng)建很耗時,所以我們采取以下方案進行Webview的優(yōu)化:

  • 預先創(chuàng)建WebView,提前將其內(nèi)核初始化。
  • 使用WebView緩存池,從緩存池中拿到Webview實例。
  • 本地提供靜態(tài)頁面資源。 

7)避免布局嵌套

如果啟動頁和主頁的布局比較復雜,也會影響我們的啟動時間,所以注意我們的布局,多用merge,include,constraintlayout等,特別是多層嵌套問題。

到此,關(guān)于“啟動優(yōu)化的方法有哪些”的學習就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關(guān)知識,請繼續(xù)關(guān)注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI