「深入理解Android布局優(yōu)化 2」-常見工具的使用

前言

本篇文章是《深入理解Android布局優(yōu)化》系列文章的第二篇。系列的主要目的是希望將Android開發(fā)中涉及布局優(yōu)化的部分做一次系統(tǒng)的歸納、總結(jié)和學(xué)習(xí)。本系列文章包含理論基礎(chǔ)、常見工具項(xiàng)目實(shí)踐三個(gè)部分。

理論基礎(chǔ):「深入理解Android布局優(yōu)化 1」-布局的加載流程與繪制原理,主要講解布局的加載流程與繪制原理,從源碼上發(fā)現(xiàn)布局的性能瓶頸。

常見工具:「深入理解Android布局優(yōu)化 2」-常見工具的使用,主要講解Android布局優(yōu)化時(shí)各種常見工具的使用。

項(xiàng)目實(shí)踐:以一個(gè)實(shí)際的APP為例,將學(xué)習(xí)到的理論和工具,實(shí)際運(yùn)用到Android開發(fā)中。

本文中實(shí)踐時(shí)使用的項(xiàng)目地址:https://github.com/linux-link/Fan,可以先閱讀這篇文章了解這個(gè)項(xiàng)目一次組件化與Android Jetpack的實(shí)踐

本篇屬于三個(gè)部分中的常見工具部分。

目錄

  • 工具集
  • GPU過(guò)度繪制
  • 渲染耗時(shí)
  • Layout Inspector
  • Choreographer
  • Systrace
  • Matrix
  • 總結(jié)

正文

一、工具集

在Android的布局優(yōu)化中也有大量的工具可供選擇,這里整理了一些常用且易于上手的工具,如下所示

工具 能力 上手難度
GPU過(guò)度繪制 發(fā)現(xiàn)布局過(guò)度嵌套
GPU呈現(xiàn)模式分析 統(tǒng)計(jì)布局繪制耗時(shí)
Layout Inspector 列出布局樹
Choreographer 統(tǒng)計(jì)界面的FPS
Systrace 統(tǒng)計(jì)進(jìn)程的內(nèi)核信息
Matrix 全方位發(fā)現(xiàn)Android中的性能問題

二、GPU過(guò)度繪制

過(guò)度繪制(Overdraw)描述的是屏幕上的某個(gè)像素在同一幀的時(shí)間內(nèi)被繪制了多次。在多層次的UI結(jié)構(gòu)里面, 如果不可見的UI也在做繪制的操作,這就會(huì)導(dǎo)致某些像素區(qū)域被繪制了多次。這就浪費(fèi)大量的CPU以及GPU資源。


過(guò)度繪制
  • 藍(lán)色: 代表1層覆蓋。像素繪制了兩次。大片的藍(lán)色還是可以接受的,若整個(gè)窗口是藍(lán)色的,可以擺脫一層。
  • 綠色: 代表2層覆蓋。像素繪制了三次。中等大小的綠色區(qū)域是可以接受的但你應(yīng)該嘗試優(yōu)化、減少它們。
  • 淡紅: 代表3層覆蓋倍。像素繪制了四次,小范圍可以接受。
  • 深紅: 代表4層覆蓋。像素繪制了五次或者更多。

以MIUI系統(tǒng)為例,展示如何打開GPU過(guò)度繪制,更多設(shè)置 -> 開發(fā)者選項(xiàng) -> 調(diào)試GPU過(guò)度繪制 -> 顯示過(guò)度繪制區(qū)域。

GPU過(guò)度繪制

理論上來(lái)說(shuō)深紅色的區(qū)域是需要重點(diǎn)優(yōu)化的對(duì)象,我們需要盡可能減少過(guò)度繪制,不過(guò)在實(shí)際項(xiàng)目中需要根據(jù)開發(fā)的具體情況來(lái)靈活判斷。

qq中存在的過(guò)度繪制現(xiàn)象

三、GPU呈現(xiàn)模式分析

渲染耗時(shí)顧名思義就是APP的界面在渲染過(guò)程中消耗的時(shí)間,在Android中每一楨的渲染耗時(shí)控制在16ms以內(nèi),則不會(huì)產(chǎn)生卡頓的感覺。

以MIUI系統(tǒng)為例,展示如何查看渲染耗時(shí)。選擇更多設(shè)置->開發(fā)者選項(xiàng)->GPU呈現(xiàn)模式分析->在屏幕上顯示為條形圖

開啟渲染耗時(shí)

開啟之后,在手機(jī)中查看任意界面,界面上都會(huì)滾動(dòng)顯示垂直的柱狀圖來(lái)表示每幀畫面所需要渲染的時(shí)間,柱狀圖越高表示花費(fèi)的渲染時(shí)間越長(zhǎng)。如圖所示

渲染耗時(shí)條形圖

從Android 6.0之后每一楨的繪制大致有個(gè)8個(gè)步驟:


繪制步驟
  • Swap Buffers

    表示處理任務(wù)的時(shí)間,也可以說(shuō)是CPU等待GPU完成任務(wù)的時(shí)間,線條越高,表示GPU做的事情越多;

  • Command Issue

    表示執(zhí)行任務(wù)的時(shí)間,這部分主要是Android進(jìn)行2D渲染顯示列表的時(shí)間,為了將內(nèi)容繪制到屏幕上,Android需要使用Open GL ES的API接口來(lái)繪制顯示列表,紅色線條越高表示需要繪制的視圖更多;

  • Sync & Upload

    表示的是準(zhǔn)備當(dāng)前界面上有待繪制的圖片所耗費(fèi)的時(shí)間,為了減少該段區(qū)域的執(zhí)行時(shí)間,我們可以減少屏幕上的圖片數(shù)量或者是縮小圖片的大?。?/p>

  • Draw

    表示測(cè)量和繪制視圖列表所需要的時(shí)間,藍(lán)色線條越高表示每一幀需要更新很多視圖,或者View的onDraw方法中做了耗時(shí)操作;

  • Measure/Layout

    表示布局的onMeasure與onLayout所花費(fèi)的時(shí)間,一旦時(shí)間過(guò)長(zhǎng),就需要仔細(xì)檢查自己的布局是不是存在嚴(yán)重的性能問題;

  • Animation

    表示計(jì)算執(zhí)行動(dòng)畫所需要花費(fèi)的時(shí)間,包含的動(dòng)畫有ObjectAnimator,ViewPropertyAnimator,Transition等等。一旦這里的執(zhí)行時(shí)間過(guò)長(zhǎng),就需要檢查是不是使用了非官方的動(dòng)畫工具或者是檢查動(dòng)畫執(zhí)行的過(guò)程中是不是觸發(fā)了讀寫操作等等;

  • Input Handling

    表示系統(tǒng)處理輸入事件所耗費(fèi)的時(shí)間,粗略等于對(duì)事件處理方法所執(zhí)行的時(shí)間。一旦執(zhí)行時(shí)間過(guò)長(zhǎng),意味著在處理用戶的輸入事件的地方執(zhí)行了復(fù)雜的操作;

  • Misc Time/Vsync Delay

    表示在主線程執(zhí)行了太多的任務(wù),導(dǎo)致UI渲染跟不上vSync的信號(hào)而出現(xiàn)掉幀的情況;

四、Layout Inspector

關(guān)于Layout Inspector的使用,google的官方中文文檔說(shuō)的非常詳細(xì),強(qiáng)烈推薦仔細(xì)閱讀,以下內(nèi)容節(jié)選自官方文檔,更多更詳細(xì)的內(nèi)容,請(qǐng)仔細(xì)閱讀官方文檔使用 Layout Inspector 調(diào)試布局。

利用 Android Studio 中的布局檢查器,可以在運(yùn)行時(shí)從 Android Studio IDE 內(nèi)檢查自己應(yīng)用的視圖層次結(jié)構(gòu)。 如果布局在運(yùn)行時(shí)(而不是完全在 XML 中)構(gòu)建并且布局沒有按預(yù)期顯示,這種檢查將非常有用。

按以下步驟操作,打開布局檢查器:

  1. 在連接的設(shè)備或模擬器上運(yùn)行您的應(yīng)用。

  2. 點(diǎn)擊Tools > Android > Layout Inspector

  3. 在出現(xiàn)的Choose Process對(duì)話框中,選擇您想要檢查的應(yīng)用進(jìn)程,然后點(diǎn)擊OK。

    Choose Process 對(duì)話框

    默認(rèn)情況下,Choose Process對(duì)話框僅會(huì)為 Android Studio 中當(dāng)前打開的項(xiàng)目列出進(jìn)程,并且該項(xiàng)目必須在設(shè)備上運(yùn)行。 如果您想要檢查設(shè)備上的其他應(yīng)用,請(qǐng)點(diǎn)擊Show all processes。 如果您正在使用已取得 root 權(quán)限的設(shè)備或者沒有安裝 Google Play 商店的模擬器,那么您會(huì)看到所有正在運(yùn)行的應(yīng)用。 否則,您只能看到可以調(diào)試的運(yùn)行中應(yīng)用。

布局檢查器會(huì)捕獲快照,將它保存為.li文件并打開。 如圖 2 中所示,布局檢查器將顯示以下內(nèi)容:

  1. View Tree:視圖在布局中的層次結(jié)構(gòu)。
  2. Screenshot:帶每個(gè)視圖可視邊界的設(shè)備屏幕截圖。
  3. Properties Table:選定視圖的布局屬性。
    布局檢查器

可以在View Tree中點(diǎn)擊視圖以在屏幕截圖中選擇相同視圖,反之亦然。 視圖的所有布局屬性都將顯示在Properties Table中。

如果布局包括重疊視圖,則默認(rèn)情況下,只有前面的視圖可以在屏幕截圖中點(diǎn)擊。 要讓后面的視圖可以在屏幕截圖中點(diǎn)擊,請(qǐng)執(zhí)行以下操作: 在View Tree中右鍵點(diǎn)擊前面的視圖,然后取消選中Show in preview。 此操作不會(huì)讓視圖內(nèi)容消失;僅會(huì)讓屏幕截圖中的可點(diǎn)擊邊界消失,以便您可以點(diǎn)擊在它后面的視圖。

如果設(shè)備上的布局發(fā)生變化,布局檢查器不會(huì)更新。 必須再次點(diǎn)擊Tools > Android > Layout Inspector,創(chuàng)建一個(gè)新的快照。每一個(gè)快照都將保存到project-name/captures/內(nèi)一個(gè)單獨(dú)的.li文件中。

Project 窗口中的布局檢查器快照(.li 文件)

五、Choreographer

上面介紹的幾種檢測(cè)方式只適合線下使用,如果我們需要在線上獲取已經(jīng)發(fā)布APP的卡頓情況,則適合使用Choreographer。

通過(guò) Choreographer.getInstance().postFrameCallback(),可以獲得當(dāng)前的界面的FPS,通過(guò)檢查一段時(shí)間內(nèi)的FPS值,我們就可以得知當(dāng)前界面是否發(fā)生了卡頓。

    private static final long MONITOR_INTERVAL = 1600L; //單次計(jì)算FPS使用1600毫秒
    private static final long MONITOR_INTERVAL_NANOS = MONITOR_INTERVAL * 1000L * 1000L;//顯示fps的間隔時(shí)間,1.6秒
    private static final long MAX_INTERVAL = 1000L; //設(shè)置計(jì)算fps的單位時(shí)間間隔1000ms,即fps/s;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(flipView);
        Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
            @Override
            public void doFrame(long frameTimeNanos) {
                if (lastFrameTime == 0) {
                    lastFrameTime = frameTimeNanos;
                }
                long interval = frameTimeNanos - lastFrameTime;
                if (interval > MONITOR_INTERVAL_NANOS) {
                    double fps = (((double) (frameCount * 1000L * 1000L)) / interval) * MAX_INTERVAL;
                    Log.e("fps:", fps + "");
                    frameCount = 0;
                    lastFrameTime = 0;
                } else {
                    ++frameCount;
                }
                Choreographer.getInstance().postFrameCallback(this);
            }
        });

    }
2019-06-28 22:10:18.918 24460-24460/com.link.flipview E/fps:: 61.04245124020559
2019-06-28 22:10:19.098 24460-24460/com.link.flipview E/fps:: 61.04702584262233
2019-06-28 22:10:19.278 24460-24460/com.link.flipview E/fps:: 61.047967231502405
2019-06-28 22:10:19.459 24460-24460/com.link.flipview E/fps:: 61.04632000634784
2019-06-28 22:10:19.639 24460-24460/com.link.flipview E/fps:: 61.04324641755805
2019-06-28 22:10:19.819 24460-24460/com.link.flipview E/fps:: 61.046939755064415
2019-06-28 22:10:19.999 24460-24460/com.link.flipview E/fps:: 61.050491907012486
2019-06-28 22:10:20.179 24460-24460/com.link.flipview E/fps:: 61.042186309896735
2019-06-28 22:10:20.360 24460-24460/com.link.flipview E/fps:: 61.04657118380607
2019-06-28 22:10:20.541 24460-24460/com.link.flipview E/fps:: 61.048108852294455

六、Systrace

Systrace是Android性能優(yōu)化時(shí)非常常用的工具,它可以記錄短時(shí)間內(nèi)的設(shè)備活動(dòng)情況,并生成一份Android內(nèi)核中的數(shù)據(jù)報(bào)告,例如CPU調(diào)度程序,磁盤活動(dòng)和應(yīng)用程序線程等等。

Systrace生成的報(bào)告如圖所示:

Systrace HTML報(bào)告示例

此報(bào)告提供了Android設(shè)備在給定時(shí)間段內(nèi)的系統(tǒng)進(jìn)程的總體情況。該報(bào)告還檢查捕獲的跟蹤信息,以突出顯示它所觀察到的問題,例如UI jank或高功耗。

注意:Systrace工具不會(huì)收集有關(guān)應(yīng)用程序進(jìn)程中代碼執(zhí)行的信息。有關(guān)應(yīng)用程序正在執(zhí)行的方法以及它使用的CPU資源的更多詳細(xì)信息,請(qǐng)使用Android Studio中的CPU分析器。您還可以 使用CPU Profiler 生成跟蹤日志并導(dǎo)入和檢查它們。

Systrace指南

要了解有關(guān)Systrace工具的更多信息,請(qǐng)參閱以下官方指南,或者閱讀這篇官方文檔的譯文:https://www.cnblogs.com/andy-songwei/p/10659564.html

七、Matrix

Matrix 是一款微信研發(fā)并日常使用的應(yīng)用性能接入框架,支持iOS, macOS和Android。 Matrix 通過(guò)接入各種性能監(jiān)控方案,對(duì)性能監(jiān)控項(xiàng)的異常數(shù)據(jù)進(jìn)行采集和分析,輸出相應(yīng)的問題分析、定位與優(yōu)化建議,從而幫助開發(fā)者開發(fā)出更高質(zhì)量的應(yīng)用。

Matrix-android 當(dāng)前監(jiān)控范圍包括:應(yīng)用安裝包大小,幀率變化,啟動(dòng)耗時(shí),卡頓,慢方法,SQLite 操作優(yōu)化,文件讀寫,內(nèi)存泄漏等等。

  • APK Checker: 針對(duì) APK 安裝包的分析檢測(cè)工具,根據(jù)一系列設(shè)定好的規(guī)則,檢測(cè) APK 是否存在特定的問題,并輸出較為詳細(xì)的檢測(cè)結(jié)果報(bào)告,用于分析排查問題以及版本追蹤

  • Resource Canary: 基于 WeakReference 的特性和 Square Haha 庫(kù)開發(fā)的 Activity 泄漏和 Bitmap 重復(fù)創(chuàng)建檢測(cè)工具

  • Trace Canary: 監(jiān)控界面流暢性、啟動(dòng)耗時(shí)、頁(yè)面切換耗時(shí)、慢函數(shù)及卡頓等問題
    SQLite Lint: 按官方最佳實(shí)踐自動(dòng)化檢測(cè) SQLite 語(yǔ)句的使用質(zhì)量

  • IO Canary: 檢測(cè)文件 IO 問題,包括:文件 IO 監(jiān)控和 Closeable Leak 監(jiān)控

關(guān)于Matrix就簡(jiǎn)單介紹到這里,更多更詳細(xì)的資料以及使用幫助請(qǐng)查閱官方文檔:
https://github.com/Tencent/matrix#matrix_cn

八、總結(jié)

本篇文章梳理了6種不同的UI優(yōu)化工具,這些工具中大多都比較常用,其中比較重要的有Layout Inspector和Systrace,Matrix因?yàn)樾枰氲谌娇蚣?,在?shí)際項(xiàng)目可以根據(jù)需要決定是否使用。下一篇將以一個(gè)《飯fan》的源碼為例,通過(guò)運(yùn)用這三種工具來(lái)發(fā)現(xiàn)、解決項(xiàng)目中性能問題。

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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