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

  • 做開發(fā)除了實(shí)現(xiàn)功能涨缚,還要注重優(yōu)化,性能優(yōu)化包括的東西還是非常多的策治,包體大小脓魏、啟動(dòng)速度、內(nèi)存通惫、數(shù)據(jù)結(jié)構(gòu)茂翔、ANR、卡頓等等履腋。
  • 用戶都希望APP按下珊燎,就能馬上進(jìn)入首頁使用,手機(jī)性能很重要遵湖,但不能要求用戶換手機(jī)悔政,于是我們就需要APP想辦法優(yōu)化啟動(dòng)的速度,不然這APP可能會(huì)被刪掉奄侠。
  • Android性能優(yōu)化 - 卡頓和布局優(yōu)化 可以一起學(xué)習(xí)卓箫。

1.啟動(dòng)的狀態(tài)

  • 我們APP不是微信那種體量,所以幾乎不可能有廠商給我們搞特殊垄潮,一直掛在那烹卒,大多數(shù)情況下都是冷啟動(dòng)闷盔,優(yōu)化也是主要優(yōu)化冷啟動(dòng)。
  • 冷啟動(dòng)
    冷啟動(dòng)是指應(yīng)用從頭開始啟動(dòng):系統(tǒng)進(jìn)程在冷啟動(dòng)后才創(chuàng)建應(yīng)用進(jìn)程旅急。發(fā)生冷啟動(dòng)的情況包括應(yīng)用自設(shè)備啟動(dòng)后或系統(tǒng)終止應(yīng)用后首次啟動(dòng)逢勾。
  • 熱啟動(dòng)
    在熱啟動(dòng)中,系統(tǒng)的所有工作就是將 Activity 帶到前臺(tái)藐吮。只要應(yīng)用的所有 Activity 仍駐留在內(nèi)存中溺拱,應(yīng)用就不必重復(fù)執(zhí)行對(duì)象初始化、布局加載和繪制谣辞。比如回到桌面迫摔,不殺掉APP的時(shí)間內(nèi)又回來。
  • 溫啟動(dòng)
    溫啟動(dòng)包含了在冷啟動(dòng)期間發(fā)生的部分操作泥从;同時(shí)句占,它的開銷要比熱啟動(dòng)高。有許多潛在狀態(tài)可視
    為溫啟動(dòng)躯嫉。例如:
    1.用戶在退出應(yīng)用后又重新啟動(dòng)應(yīng)用纱烘。進(jìn)程可能未被銷毀,繼續(xù)運(yùn)行祈餐,但應(yīng)用需要執(zhí)行
    onCreate() 從頭開始重新創(chuàng)建 Activity擂啥。
    2.系統(tǒng)將應(yīng)用從內(nèi)存中釋放,然后用戶又重新啟動(dòng)它帆阳。進(jìn)程和 Activity 需要重啟哺壶,但傳遞到
    onCreate() 的已保存的實(shí)例 state bundle 對(duì)于完成此任務(wù)有一定助益。

2.冷啟動(dòng)耗時(shí)

  • 2-5-8原則:
  • 當(dāng)用戶能夠在2秒以內(nèi)得到響應(yīng)時(shí)蜒谤,會(huì)感覺系統(tǒng)的響應(yīng)很快变骡;
  • 當(dāng)用戶在2-5秒之間得到響應(yīng)時(shí),會(huì)感覺系統(tǒng)的響應(yīng)速度還可以芭逝;
  • 當(dāng)用戶在5-8秒以內(nèi)得到響應(yīng)時(shí),會(huì)感覺系統(tǒng)的響應(yīng)速度很慢渊胸,但是還可以接受旬盯;
  • 而當(dāng)用戶在超過8秒后仍然無法得到響應(yīng)時(shí),會(huì)感覺系統(tǒng)糟透了翎猛,或者認(rèn)為系統(tǒng)已經(jīng)失去響應(yīng)胖翰。

2.1 系統(tǒng)日志統(tǒng)計(jì)

  • Logcat,篩選 Displayed切厘,就能看到啟動(dòng)時(shí)長(zhǎng)萨咳。
  • 這個(gè)時(shí)長(zhǎng)就是應(yīng)用啟動(dòng)到顯示對(duì)應(yīng)的Activity繪制完成的時(shí)長(zhǎng)。(下圖就是啟動(dòng)到MainActivity)


    日志查看啟動(dòng)時(shí)長(zhǎng)

2.2 adb命令統(tǒng)計(jì)

  • adb需要配置環(huán)境變量疫稿,只需要把 sdk 目錄下的 platform-tools 路徑添加到 環(huán)境變量path 里面就行培他。

    配置adb環(huán)境變量

  • adb shell

  • am shart -S -W com.bao.myapplication/.MainActivity

  • 根據(jù)自己的包名和要啟動(dòng)的Activity輸入這兩行命令就可以看到啟動(dòng)時(shí)間鹃两。

  • TotalTime就是啟動(dòng)時(shí)長(zhǎng)啦。

    adb查看啟動(dòng)時(shí)長(zhǎng)

3.啟動(dòng)分析

3.1 CPU Profile工具簡(jiǎn)單教程

  • Android Studio 功能越來越完善俊扳,我們可以利用 CPU Profile 來查看分析啟動(dòng)時(shí)做了什么事情。

  • 點(diǎn)擊 app -> Edit Configurations猛遍。

    cpu profile

  • Profilling -> Start recording CPU activity on startup馋记。

  • 選擇CPU記錄配置 Trace Java Methods

    選擇CPU記錄配置

  • 這四種模式官方文檔也有詳細(xì)說明懊烤。

  • 1.對(duì) Java 方法采樣:在應(yīng)用的 Java 代碼執(zhí)行期間梯醒,頻繁捕獲應(yīng)用的調(diào)用堆棧。分析器會(huì)比較捕獲的數(shù)據(jù)集腌紧,以推導(dǎo)與應(yīng)用的 Java 代碼執(zhí)行有關(guān)的時(shí)間和資源使用信息茸习。
    基于采樣的跟蹤存在一個(gè)固有的問題,那就是如果應(yīng)用在捕獲調(diào)用堆棧后進(jìn)入一個(gè)方法并在下次捕獲前退出該方法寄啼,分析器將不會(huì)記錄該方法調(diào)用逮光。如果您想要跟蹤生命周期如此短的方法,應(yīng)使用插樁跟蹤墩划。

  • 2.跟蹤 Java 方法:在運(yùn)行時(shí)檢測(cè)應(yīng)用涕刚,從而在每個(gè)方法調(diào)用開始和結(jié)束時(shí)記錄一個(gè)時(shí)間戳。系統(tǒng)會(huì)收集并比較這些時(shí)間戳乙帮,以生成方法跟蹤數(shù)據(jù)杜漠,包括時(shí)間信息和 CPU 使用率。
    請(qǐng)注意察净,與檢測(cè)每個(gè)方法相關(guān)的開銷會(huì)影響運(yùn)行時(shí)性能驾茴,并且可能會(huì)影響分析數(shù)據(jù);對(duì)于生命周期相對(duì)較短的方法氢卡,這一點(diǎn)更為明顯锈至。此外,如果應(yīng)用在短時(shí)間內(nèi)執(zhí)行大量方法译秦,則分析器可能很快就會(huì)超出其文件大小限制峡捡,因而不能再記錄更多跟蹤數(shù)據(jù)。

  • 3.對(duì) C/C++ 函數(shù)采樣:捕獲應(yīng)用的原生線程的采樣跟蹤數(shù)據(jù)筑悴。如需使用此配置们拙,您必須將應(yīng)用部署到搭載 Android 7.0(API 級(jí)別 24)或更高版本的設(shè)備上。
    在內(nèi)部阁吝,此配置使用 simpleperf 跟蹤應(yīng)用的原生代碼砚婆。如果需為 simpleperf 指定其他選項(xiàng),如對(duì)特定設(shè)備 CPU 采樣或指定高精度采樣持續(xù)時(shí)間突勇,您可以從命令行使用 simpleperf装盯。

  • 4.跟蹤系統(tǒng)調(diào)用:捕獲非常翔實(shí)的細(xì)節(jié)坷虑,以便您檢查應(yīng)用與系統(tǒng)資源的交互情況。您可以檢查線程狀態(tài)的確切時(shí)間和持續(xù)時(shí)間验夯、直觀地查看所有內(nèi)核的 CPU 瓶頸在何處猖吴,并添加需分析的自定義跟蹤事件。當(dāng)您排查性能問題時(shí)挥转,此類信息至關(guān)重要海蔽。如需使用此配置,您必須將應(yīng)用部署到搭載 Android 7.0(API 級(jí)別 24)或更高版本的設(shè)備上绑谣。
    使用此跟蹤配置時(shí)党窜,您可以通過檢測(cè)代碼,在分析器時(shí)間軸上直觀地標(biāo)記重要的代碼例程借宵。如需檢測(cè) C/C++ 代碼幌衣,請(qǐng)使用由 trace.h 提供的原生跟蹤 API。如需檢測(cè) Java 代碼壤玫,請(qǐng)使用 Trace 類豁护。如需了解詳情,請(qǐng)參閱檢測(cè)您的應(yīng)用代碼欲间。

    此跟蹤配置建立在 systrace 的基礎(chǔ)之上楚里。您可以使用 systrace 命令行實(shí)用程序指定除 CPU 性能剖析器提供的選項(xiàng)之外的其他選項(xiàng)。systrace 提供的其他系統(tǒng)級(jí)數(shù)據(jù)可幫助您檢查原生系統(tǒng)進(jìn)程并排查丟幀或幀延遲問題猎贴。

  • 設(shè)置好了之后就啟動(dòng)Profile班缎。


    啟動(dòng)Profile
  • 當(dāng)你看到自己APP,CPU的使用率比較低的時(shí)候她渴,差不多就是啟動(dòng)完成了达址,點(diǎn)一下stop。


    在這里插入圖片描述

3.2 啟動(dòng)耗時(shí)分析

  • Call Chart 雙擊要看的線程趁耗,就能看到從上到下沉唠,方法執(zhí)行的時(shí)長(zhǎng),除了系統(tǒng)的方法苛败,綠色是自己的代碼右冻,就能看到耗時(shí)了,這里的方法是按時(shí)間線排列的著拭,從啟動(dòng)到完成的過程。

    Call Chart

  • Top Down標(biāo)簽顯示一個(gè)調(diào)用列表牍帚,在該列表中展開方法或函數(shù)節(jié)點(diǎn)會(huì)顯示它的被調(diào)用方儡遮。下圖可以看到我在自定義View里面放了一個(gè)Thread.sleep,休眠了3秒。

    Top Down

  • Flame Chart火焰圖橫向代表方法時(shí)長(zhǎng)暗赶,向上就是被調(diào)用的方法鄙币,我們也能看到自定義View里面的sleep明顯比其他長(zhǎng)肃叶。

    Flame Chart

3.3 使用Debug Api 生成.trace文件

  • 在Application onCreate 方法加入 Debug.startMethodTracing()
  • 在MainActivitu onWindowFocusChanged(boolean hasFocus) 方法加入 Debug.stopMethodTracing()十嘿。
public class BaoApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        Debug.startMethodTracing("baoTest");
    }
}

public class MainActivity extends AppCompatActivity {
   .
   .
   . 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        .
        .
        .
    }

    /**
     * MainActivity 停止啟動(dòng)分析的地方
     * @param hasFocus
     */
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        Debug.stopMethodTracing();
    }
}
  • 默認(rèn)在自己應(yīng)用的目錄下生成 .trace 文件因惭,復(fù)制到自己電腦目錄下。
    .trace文件目錄
  • 拖到Android Studio绩衷,就可以查看結(jié)果了蹦魔。


    拖進(jìn)去分析

4.StrictMode嚴(yán)苛模式

  • 開發(fā)時(shí)開啟嚴(yán)苛模式,提示我們咳燕。
  @Override
    public void onCreate() {
        super.onCreate();
        if (BuildConfig.DEBUG) {
            //線程檢測(cè)
            StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                    .detectDiskReads()
                    .detectDiskWrites()
                    .detectNetwork()
                    .penaltyLog()
                    .build());

            StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
                    .detectLeakedSqlLiteObjects()//數(shù)據(jù)庫對(duì)象泄漏
                    .detectLeakedClosableObjects()//未關(guān)閉的對(duì)象泄漏
                    .penaltyDeath()//違規(guī)奔潰
                    .penaltyLog()//違規(guī)日志
                    .build());
        }
    }

5.結(jié)尾

  • 簡(jiǎn)化布局勿决,布局層級(jí)不要太多可以提高啟動(dòng)速度(熟練使用約束布局可以減少層級(jí)),啟動(dòng)和主線程不要做耗時(shí)操作招盲。
  • 啟動(dòng)盡量別搞什么sleep休眠之類的低缩,就算不報(bào)錯(cuò),但也不好查找曹货。
  • 有的APP會(huì)有啟動(dòng)廣告咆繁,我們可以在展示廣告的時(shí)間里,利用子線程繼續(xù)初始化工作顶籽。
  • 啟動(dòng)的流程非常的多玩般,也非常復(fù)雜,一般我們能改的就是自己的APP蜕衡,通過工具分析自己的APP哪些地方比較耗時(shí)壤短,能減少的盡量減少,有一些減少非常有限慨仿,但是項(xiàng)目比較大的時(shí)候久脯,往往都是積少成多的,需要一點(diǎn)點(diǎn)去優(yōu)化镰吆。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末帘撰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子万皿,更是在濱河造成了極大的恐慌摧找,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牢硅,死亡現(xiàn)場(chǎng)離奇詭異蹬耘,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)减余,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門综苔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事如筛”つ担” “怎么了?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵杨刨,是天一觀的道長(zhǎng)晤柄。 經(jīng)常有香客問我,道長(zhǎng)妖胀,這世上最難降的妖魔是什么芥颈? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任,我火速辦了婚禮做粤,結(jié)果婚禮上浇借,老公的妹妹穿的比我還像新娘。我一直安慰自己怕品,他們只是感情好妇垢,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肉康,像睡著了一般闯估。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吼和,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天涨薪,我揣著相機(jī)與錄音,去河邊找鬼炫乓。 笑死刚夺,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的末捣。 我是一名探鬼主播侠姑,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼箩做!你這毒婦竟也來了莽红?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤邦邦,失蹤者是張志新(化名)和其女友劉穎安吁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體燃辖,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鬼店,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了黔龟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片薪韩。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡确沸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出俘陷,到底是詐尸還是另有隱情,我是刑警寧澤观谦,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布拉盾,位于F島的核電站,受9級(jí)特大地震影響豁状,放射性物質(zhì)發(fā)生泄漏捉偏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一泻红、第九天 我趴在偏房一處隱蔽的房頂上張望夭禽。 院中可真熱鬧,春花似錦谊路、人聲如沸讹躯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽潮梯。三九已至,卻和暖如春惨恭,著一層夾襖步出監(jiān)牢的瞬間秉馏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國打工脱羡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留萝究,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓锉罐,卻偏偏與公主長(zhǎng)得像帆竹,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子氓鄙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359