中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

App啟動(dòng)優(yōu)化-Android性能優(yōu)化

2018-07-20    來源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬Linux鏡像隨意使用

通常用戶期望app響應(yīng)和加載速度越快越好。一個(gè)啟動(dòng)速度慢的app很可能會(huì)給用戶留下不好的印象,除了導(dǎo)致用戶在應(yīng)用市場(chǎng)上的打分低之外,很有可能導(dǎo)致致用戶直接卸載。

這篇文章提供了優(yōu)化app啟動(dòng)時(shí)間的方法。先解釋了app進(jìn)程啟動(dòng)的內(nèi)部流程。然后討論如何優(yōu)化啟動(dòng)的性能。最后列出幾個(gè)常見的啟動(dòng)問題和解決方案。

一 啟動(dòng)內(nèi)幕

App啟動(dòng)可能發(fā)生在以下三種狀態(tài) 之一,每一種都會(huì)影響到展現(xiàn)給用戶的時(shí)間:冷啟動(dòng)、熱啟動(dòng)和溫啟動(dòng)(翻譯的有點(diǎn)怪,介于冷和熱之間吧)。

冷啟動(dòng)下,app所做的事情不較多,其它兩種情況,系統(tǒng)只需要將app從后臺(tái)切到前臺(tái)。建議你在冷啟動(dòng)的基礎(chǔ)上做優(yōu)化,這樣也會(huì)提升熱啟動(dòng)和溫啟動(dòng)的性能。

為了更好地優(yōu)化app的啟動(dòng),了解系統(tǒng)和app層做了什么以及如何相互影響很有必要。

1.1 冷啟動(dòng)

冷啟動(dòng)指:在app啟動(dòng)之前,系統(tǒng)的進(jìn)程還沒有,直到app啟動(dòng)創(chuàng)建app的進(jìn)程。冷啟動(dòng)會(huì)發(fā)生在device重啟或者app被殺死的情況下。這種啟動(dòng)在優(yōu)化啟動(dòng)時(shí)間上,有更大的挑戰(zhàn),因?yàn)橄啾绕渌鼉煞N啟動(dòng)方式,系統(tǒng)和app有更多的工作需要處理。

冷啟動(dòng)之前,系統(tǒng)會(huì)執(zhí)行以下三個(gè)task:

1、加載并啟動(dòng)app

2、在app啟動(dòng)后,立即展示空白的window

3、創(chuàng)建app進(jìn)程

一旦系統(tǒng)創(chuàng)建了app進(jìn)程,那么app進(jìn)程就會(huì)執(zhí)行以下步驟

1、創(chuàng)建app對(duì)象

2、啟動(dòng)main thread

3、創(chuàng)建MainActivity

4、Inflate view

5、布置屏幕

6、進(jìn)行首次繪制

一旦app進(jìn)程完成了第一次繪制,系統(tǒng)進(jìn)程就會(huì)用main activity替換已經(jīng)展示的background window。之后用戶才可以使用app。

下圖展示了系統(tǒng)和app進(jìn)程互相如何工作的,展示了app啟動(dòng)時(shí)期的幾個(gè)重要部分,在創(chuàng)建app和main activity之間,我們可以提升性能問題

Application的創(chuàng)建

當(dāng)應(yīng)用啟動(dòng)的時(shí)候,空白的window在app第一次完成繪制之前都會(huì)存在。在那之后,系統(tǒng)進(jìn)程才會(huì)替換啟動(dòng)窗口,允許用戶開始和app交互。

如果你復(fù)寫了 Application.oncreate() 方法,app啟動(dòng)的時(shí)候,會(huì)調(diào)用該方法。之后,app會(huì)孵化主線程(UI線程),并通過它來創(chuàng)建main activity。

從這之后,系統(tǒng)和app級(jí)別的進(jìn)程將會(huì)按照 app lifecycle stages 執(zhí)行。

Activity的創(chuàng)建

在app進(jìn)程創(chuàng)建了Activity之后,Activity將會(huì)執(zhí)行以下操作

1、初始化值

2、調(diào)用構(gòu)造函數(shù)

3、調(diào)用毀掉方法,比如Activity.onCreate()。

通常,onCreate方法會(huì)對(duì)加載時(shí)間有比較大的影響。因?yàn)樗鼘?zhí)行繁重的工作:加載和填充view,并初始化Activity運(yùn)行期間需要用的對(duì)象。

1.2 熱啟動(dòng)

相對(duì)于冷啟動(dòng),熱啟動(dòng)會(huì)簡(jiǎn)單的多。如果app的所有Activities還存在內(nèi)存中,那么系統(tǒng)需要做的就是將activity切換到前臺(tái)。這樣app會(huì)避免進(jìn)行的對(duì)象初始化,布局填充和渲染。

但是,如果一些內(nèi)存在觸發(fā)內(nèi)存回調(diào)方法的時(shí)候被回收了,比如onTrimMemory(),那么這些對(duì)象就需要重新創(chuàng)建。

熱啟動(dòng)會(huì)和冷啟動(dòng)有相同的行為。系統(tǒng)也會(huì)展示一個(gè)空白的window,知道app完成Activity的渲染。

1.3 溫啟動(dòng)

溫啟動(dòng)做的工作介于冷熱啟動(dòng)之間。這里列舉幾種可能被認(rèn)為是溫啟動(dòng)的狀態(tài):

1、用戶離開了app,然后重新啟動(dòng)它。這時(shí)進(jìn)程還在繼續(xù)運(yùn)行,但是Activity被回收了,app需要重新創(chuàng)建activity。

2、系統(tǒng)將你的app回收了,然后用戶重新啟動(dòng)app。進(jìn)程和Activity都需要重新啟動(dòng),但它們可以從onCreate方法保存的bundle中恢復(fù)。

二優(yōu)化啟動(dòng)性能

為了確定啟動(dòng)時(shí)間的性能問題,我們需要先確定app啟動(dòng)花費(fèi)了多少時(shí)間。

2.1 Time to initial display

從4.4(API 19)開始,logcat會(huì)輸出帶有Displayed的log。該值代表從app啟動(dòng)進(jìn)程到完成Activity第一次繪制的時(shí)間。該時(shí)間內(nèi)完成了一下流程:

  • 啟動(dòng)進(jìn)程
  • 初始化對(duì)象
  • 創(chuàng)建和初始化Activity
  • 填充布局
  • 第一次繪制app

打出的log如下:

ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms

如果你從命令行或者終端跟蹤log的話,可以比較直接的定位到該log。如果在AndroidStudio中,別忘記關(guān)閉filter。

Displayed值并沒有捕獲所有資源都被加載和展示的總時(shí)間。那些不在layout文件中或者創(chuàng)建app初始化所需要對(duì)象的時(shí)間不包含在內(nèi)。因?yàn)檫@些資源是在一個(gè)內(nèi)部進(jìn)程中加載的,并且不會(huì)阻塞app的初始化展示。

2.2 Time to full display

你可以調(diào)用 reportFullyDrawn() )方法去測(cè)量從應(yīng)用啟動(dòng)到所有資源和view層級(jí)都被繪制出來的時(shí)間。這對(duì)于app執(zhí)行懶加載的情況很有用。在懶加載中,app不會(huì)阻塞window的初始化繪制,但同步進(jìn)行資源加載和view的更新會(huì)阻塞。

由于懶加載,app的初始化展示不會(huì)包含所有的資源。你可以考慮完全加載并展示所有資源和view的時(shí)候作為一個(gè)考量。比如,UI可能完全加載了,包括一些text的繪制,但是由于圖片需要從網(wǎng)絡(luò)獲取,這時(shí)還沒有展示。

為了處理這種情況,你可以手動(dòng)地調(diào)用reportFullyDrawn方法讓系統(tǒng)知道你的activity已經(jīng)通過懶加載完成了。但你是用該方法的時(shí)候,logcat展示的時(shí)間就包含從應(yīng)用被創(chuàng)建到reportFullyDrawn方法被調(diào)用的時(shí)間。

定位瓶頸

兩種方式可以幫助你定位問題:AndroidStudio中的Method Tracer和內(nèi)嵌tracing代碼的方式。更多可以參考 documentation .

如果無法使用Method Tracer Tool ,或者覺得trace的時(shí)機(jī)不夠準(zhǔn)確,那么你可以通過在app和Activity的onCreate方法中嵌入代碼進(jìn)行追蹤,比如寫下追蹤代碼。更多信息,可以參考 Trace 、Systrace

三常見的問題

3.1 繁重的App初始化

當(dāng)你繼承了Application對(duì)象,又在Application對(duì)象進(jìn)行初始化的時(shí)候執(zhí)行繁重的工作或者復(fù)雜的邏輯,那么就可能導(dǎo)致啟動(dòng)的性能問題。在啟動(dòng)的時(shí)候花一些時(shí)間去初始化一些子類可能完全沒必要。

在app初始化的時(shí)候,其它的挑戰(zhàn)包括垃圾回收事件,繁重的操作,比如I/O,都有可能會(huì)阻塞進(jìn)程的初始化。對(duì)于Dalvik運(yùn)行環(huán)境來說,垃圾回收是一個(gè)需要特別考慮的點(diǎn),Art運(yùn)行環(huán)境會(huì)并發(fā)的執(zhí)行垃圾回收,以便最小化垃圾回收產(chǎn)生的影響。

3.1.1定位為題

使用method tracing或者內(nèi)嵌代碼來定位這個(gè)問題

Method tracing

Running the Method Tracer tool reveals that the callApplicationOnCreate() method eventually calls your com.example.customApplication.onCreate method. If the tool shows that these methods are taking a long time to finish executing, you should explore further to see what work is occurring there.

內(nèi)嵌代碼的方式

可以對(duì)以下代碼進(jìn)行追蹤

1、App的onCreate方法

2、onCreate中初始化的所有全局單例對(duì)象

3、所有I/O,反序列化,或者可能導(dǎo)致性能問題的循環(huán)

3.1.2 解決方案

如果是由于不必要的初始化或者硬盤I/O操作導(dǎo)致的問題,解決方案就是懶初始化對(duì)象:只初始化立即需要的。而不是在一開始就創(chuàng)建全局的靜態(tài)對(duì)象,可以將它們的初始化放在一個(gè)單例中,當(dāng)app首次訪問它們的時(shí)候再初始化對(duì)象。

3.2繁重的Activity初始化

Activity的創(chuàng)建有時(shí)會(huì)承擔(dān)大量的復(fù)雜操作。通常這里存在可以優(yōu)化的點(diǎn)。常見的問題有:

1、填充大量復(fù)雜的布局

2、硬盤操作或者網(wǎng)絡(luò)操作阻塞了繪制

3、加載或者編碼bitmap

4、柵欄化VectorDrawable對(duì)象

5、Activity中其它子系統(tǒng)的初始化

3.2.1定位問題

和定位App啟動(dòng)問題類似,也是通過method tracing或者嵌入代碼來定位。

Method tracing

當(dāng)執(zhí)行Method Tracer tool的時(shí)候,你應(yīng)該關(guān)注繼承于Application的子類的構(gòu)造函數(shù)和onCreate方法。

如果該工具表明代碼中花了很長(zhǎng)時(shí)間去執(zhí)行,那么你就應(yīng)該進(jìn)一步查看這里的具體操作。

嵌入代碼的方式

追蹤的部分可能是以下代碼塊(和App初始化一樣)

1、App的onCreate方法

2、啟動(dòng)時(shí)初始化的所有全局單例對(duì)象

3、所有I/O,反序列化,或者可能導(dǎo)致性能問題的循環(huán)

3.2.2 解決方案

上面可能有很多潛在的問題,這列舉兩種通用的問題和解決方案:

  • view的層級(jí)越龐大,app就會(huì)花越多的時(shí)間去填充它

    減少多余的或者嵌套的布局

    不填充哪些不需要在啟動(dòng)時(shí)就需要展示的view?赏ㄟ^ViewStub來實(shí)現(xiàn),在需要的時(shí)候再填充

  • 在main thread中做資源的初始化也會(huì)減慢啟動(dòng)速度?梢酝ㄟ^下面來解決

    延遲所有的資源初始化或者放在其它線程中去做

    允許app先加載和展示view,那些依賴于bitmap或者其它資源之后再去更新

三 主題化的啟動(dòng)屏幕

我們可以通過主題化app的啟動(dòng)屏幕來改善啟動(dòng)體驗(yàn)。這樣整個(gè)app的啟動(dòng)和接下來的操作會(huì)顯得更加連貫。但這樣只是將Activity的慢啟動(dòng)問題隱藏了。

一種常用的方式實(shí)現(xiàn)主題啟動(dòng)屏幕的方式是使用 windowDisablePreview 主題屬性關(guān)閉系統(tǒng)進(jìn)程在app啟動(dòng)時(shí)繪制的初始化空白屏幕。但是,這種方式會(huì)導(dǎo)致更長(zhǎng)時(shí)間。同樣的,這樣也會(huì)迫使用戶等到Activity啟動(dòng)后才會(huì)得到反饋,會(huì)讓用戶產(chǎn)生app本身是否有問題的困惑。

解決方案

建議你不應(yīng)該禁止預(yù)覽窗口,你應(yīng)該遵循 Material Design 標(biāo)準(zhǔn)。使用Activity的windowBackground主題屬性來為啟動(dòng)的Activity提供一個(gè)簡(jiǎn)單的drawable。

布局文件

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque"> <!-- The background color, preferably the same as your normal theme --> <item android:drawable="@android:color/white"/> <!-- Your product logo - 144dp color version of your app icon --> <item> <bitmap android:src="@drawable/product_logo_144dp" android:gravity="center"/> </item> </layer-list> 

Manifest file:

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

然后在代碼中將主題切換回app的主題,最簡(jiǎn)單的方式是在 super.onCreate() 和 setContentView()方法之前 調(diào)用 setTheme(R.style.AppTheme)

public class MyMainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { // Make sure this is before calling super.onCreate setTheme(R.style.Theme_MyApp); super.onCreate(savedInstanceState); // ... }
}

 

來自:http://www.lightskystreet.com/2016/10/15/android-optimize-start/

標(biāo)簽: isp 代碼 網(wǎng)絡(luò)

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:Android中的緩存

下一篇:生成全局唯一 ID 的 3 個(gè)思路