你告訴我太卡了,那是你不曉得性能優化之app卡頓優化

前言

手把手講解系列文章,是我寫給各位看官,也是寫給我本身的。文章可能過度詳細,可是這是爲了幫助到儘可能多的人,畢竟工做5,6年,不能老吸血,也到了回饋開源的時候

(更多完整項目下載。未完待續。源碼。圖文知識後續上傳github。)
能夠點擊關於我聯繫我獲取983頁完整PDF
(VX:mm14525201314)html

這個系列的文章:python

一、用通俗易懂的講解方式,講解一門技術的實用價值
二、詳細書寫源碼的追蹤,源碼截圖,繪製類的結構圖,儘可能詳細地解釋原理的探索過程
三、提供Github 的 可運行的Demo工程,可是我所提供代碼,更可能是提供思路,拋磚引玉,請酌情cv
四、集合整理原理探索過程當中的一些坑,或者demo的運行過程當中的注意事項
五、用gif圖,最直觀地展現demo運行效果

若是以爲細節太細,直接跳過看結論便可。本人能力有限,如若發現描述不當之處,歡迎留言批評指正。android

學到老活到老,路漫漫其修遠兮。與衆君共勉 !git

正文大綱

  • DDMS
  • systrace
  • TraceView
  • 關於過分繪製

正文

DDMS
DDMS 的全稱是Dalvik Debug Monitor Service,是 Android 開發環境中的Dalvik[虛擬機]調試監控服務

之前用 eclipse的時候,有個直接的入口能夠打開DDMS,可是自從用了AndroidStudio,入口沒了....可是其實在SDK目錄內部仍是有的.

打開DDMS以後:

具體有啥用,稍後再說。github

systrace

systracesdk的一個命令,它是用python語言寫的,當時用的是 python2.7,可是後來python更新了3.0 谷歌卻沒有更新這個命令,致使咱們如今要使用 systrace命令,只能用python的2.7版本,正常狀況下,用2.7的最新版2.7.16就好了,官網有下載的。

那麼systrace命令在哪裏?
chrome

前提

要使用它,首先咱們要安裝好 python2.7.16,而後配置環境變量,直到咱們可以正常使用python命令(這個不必詳述吧,囧- -!api

正戲

systrace是咱們用來抓取一段時間以內的android設備上的數據指標的工具,我理解爲: 設備運行日誌,只不過這不是文本日誌,而是一個 html文件,須要使用谷歌瀏覽器的 chrome://tracing/插件打開。具體步驟以下:瀏覽器

一、打開 CMD,進入 systrace目錄:

二、輸入 python systrace.py-b32768-t5-o mytrace.html wm gfx input view sched freq,而後回車 解釋一下這一串命令( 本文不作systrace命令的詳解,這些東西都是死命令,百度便可):
  • python 將要執行python腳本
  • systrace.py 腳本名稱
  • b 設置緩存區大小
  • t 抓取5秒日誌
  • o mytrace.html 輸出到這個文件內
  • wm WindowManager 日誌內包含windowManager信息
  • gfx Graphics 日誌中包含圖形繪製的信息

- input Input 日誌中包含設備輸入的信息緩存

  • view View System 日誌中包含View系統的信息
  • sched CPU Scheduling 日誌中包含CPU調度信息
  • freq 日誌中包含CPU頻率信息

這裏有個坑:性能優化

在某些真機上,好比 vivo X7,它會生成 html文件失敗,莫名其妙,我換成模擬器,就行了,還沒有試驗其它真機機型。

我使用網易mumu模擬器作實驗的時候,獲得以下結果:

三、獲得文件以後,打開谷歌瀏覽器:在地址欄輸入 chrome://tracing/ 而後load剛纔的文件:( 或者你雙擊該html文件)

四、這裏咱們獲得了很是多的性能指標,包括上圖中紅色字體標記的CPU用量,多核CPU調度狀況,UI主線程,渲染線程等,可是咱們應用層開發,解決的主要是app卡頓問題,通常只須要 去關注 UI主線程的掉幀狀況便可. 按照下圖:


詳解一下這個 帶圈的F:

  • 整個座標,橫軸爲時間,從左到右時間刻度增長,表明各項指標隨着時間的變化
  • 帶圈的F : 有綠色,黃色和紅色。其中綠色表示繪製正常,無需咱們去關心,須要關注的是 黃色和紅色,特別是紅色。
  • 鼠標點擊其中一個紅色的F,而後按鍵盤 G鍵,就會出現 紅色的豎線,每兩根紅線之間表明一幀的時長(大部分手機的屏幕刷新頻率仍是60幀,因此每次繪製大概是 16.67MS),這個F之因此是紅色,是由於這一次的UI繪製時長遠遠超過了1幀,若是UI在1幀時間以內沒法完成,便會形成掉幀,一旦掉幀,在用戶的感知下,就是卡頓.

看下圖:

使用鼠標拖拽,能夠經過圖形界面看到這一次繪製所花費的時長:爲 116.868ms

  • 在下面的Alert欄中發現了疑似 掉幀元兇


這裏反映出,是咱們的 bitmap圖上傳致使了掉幀。咱們繼續把下面兩個箭頭開,可以看到:

這裏的英文描述,則是 谷歌工程師給咱們的建議.我來大概翻譯一下這段話:

第一段的 description意思是: 修改/新繪製的位圖必須上傳到GPU。由於若是上傳的總像素量很大,這是很昂貴的,因此每幀減小這個動畫/上下文中位圖的波動量。

第二段 description的意思是: 生成這個幀的工做被從新調度了幾毫秒,這是jank的功勞。確保UI線程上的代碼不會阻塞其餘線程上的工做,而且後臺線程(例如網絡或位圖加載)在android.os上運行。進#THREAD_PRIORITY_BACKGROUND或更低,所以它們不太可能中斷UI線程。這些後臺線程應該在內核進程的調度部分以130或更高的優先級出現。 總的來講,就是 Bitmap的使用不當致使掉幀,解決方法大概是:bitmap太大了 要裁剪成合適的大小 或者在背景線程去加載 至於更加具體的其餘掉幀狀況的解決方法,就要根據具體遇到的狀況去查資料了。

關於Trace.beginSectionTrace.endSection
這兩個apiandroidSdk自帶的,做用是給systrace加上tag,加了tag,就會在systrace圖形上反映出咱們這兩個api之間囊括的一段代碼的執行狀況。簡單來講,就是你在 一段代碼的先後,加上 Trace.beginSectionTrace.endSection ,像這樣:

那麼,你在 systrace圖形上就會發現這個。

可見,咱們代碼的執行耗時等狀況能夠 反映在 systrace圖形上,點擊上面紅框的區域,就會在 systrace界面底部發現:

若是加了tag的代碼的執行耗時超過了一幀時長(16.67MS),則說明這一段代碼形成了UI主線程掉幀,用戶就有可能感受到卡頓。

這裏有個坑
若是你上面加了trace.beginSection和endSection,你在圖形中仍是沒有看到 你本身設置的tag,那麼檢查一下你的 systrace命令,是否是沒有加 -a [app包名]

作個結論

上述例子,我使用的是app冷啓動時抓的 systrace,因此這裏的掉幀,就是反映出冷啓動過程當中代碼寫的有問題。注意,抓 systrace的時間不要太長,必須在 systrace開始執行以後再操做app。

在發現掉幀的狀況以後,看alert就能看出谷歌給咱們的app優化方向建議,雖然尚未徹底解決問題,可是至少肯定了一個大方向,知道了大概哪一段代碼出了問題。

TraceView

在app代碼中加入 Debug.startMethodTracing("/sdCard/zhouzhou");Debug.stopMethodTracing(); 而後運行app,確保可以執行上面兩個代碼包含的代碼片斷 。好比像這樣: image

坑坑

上面的代碼,若是你加了以後運行直接拋了異常,檢查一下你有沒有加這個權限: <uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

接下來,找到這個文件,導出到電腦上:

而後就要用到咱們最早說道的DDMS,先打開DDMS,File- openFile 打開剛纔的.trace文件

這裏包含了這段代碼中全部的方法調用。

表格說明

上方有一張表格,每一列的說明以下:

這麼多東西,咱們不可能全都關注,只須要關注兩個:

  • CpuTime/Call 函數平均執行時間較長的函數;(耗時較長的函數)
  • Call+RecurCalls/Total,調用次數很是頻繁的函數。若是發現,上面兩個指標超乎尋常,好比調用次數特別多,每一次調用耗費時間特別長的,並且又可以是咱們本身寫的方法,那麼基本上就能肯定優化點了。

關於過分繪製

概念:若是屏幕的一片區域,在渲染的過程當中,被繪製了太屢次,則稱爲過分繪製。如何檢查:

上圖是mumu模擬器的設置界面,咱們點擊 顯示過分繪製區域,就會發現界面顏色發生了變化:

顏色由淺到深,越深,表示過渡繪製會越嚴重。大體有如下幾種顏色:

  1. 白色:沒有過分繪製。
  2. 藍色:Overdraw 一倍。像素繪製了兩次,可以接受,可是若是整個界面都是藍色的,那麼說明仍是有繪製的浪費,能夠節約一層繪製。
  3. 綠色:Overdraw 兩倍。嘗試優化。
  4. 淺紅:Overdraw 三倍。
  5. 暗紅:Overdraw 四倍。很是嚴重,必須優化。

如何優化過渡繪製?

  1. 若是你的代碼中,經過過分繪製的檢查,發現複雜佈局顯示出大量的過分繪製,那麼必需要考慮 用自定義View本身去繪製
  2. 若是你的佈局xml中,有大量的嵌套,考慮 去掉某些background ,由於沒有了background,UI線程就不會去作這一次繪製
  3. 若是非要用到有background的layout,那麼在知足業務需求的狀況下考慮 減小必定的層級

結語

上述3個工具的使用,是咱們app性能優化中必須用到的。大概思路以下

1.用systrace 抓取 .html文件,觀察圖形,找出掉幀的大概位置

2. 用 Trace.beginSection 和 Trace.endSection 反覆推測,肯定確切代碼塊

3. 用traceView抓取.trace日誌,用DDMS打開它,尋找耗時較長的函數 或 次數很是多的函數,肯定確切掉幀緣由

三個工具須要結合使用,才能具體肯定咱們的 app哪裏出了問題。

話題拓展

本文只給出了大體思路,並無給出Demo,這是由於 性能優化可能出現的狀況太多了,沒法一一列舉,具體發生了什麼,只有到發生以後,自行根據工具檢測出的結果去推斷,去論證,去解決。

性能優化是無止境的,永遠有可以優化的空間。本文只給出了大體指導方向,具體可以優化到何種程度,全看各位的自我修爲。**

上面的3個工具,能夠用來作性能優化, 可是他們的做用不只僅是性能優化,千萬不要一葉障目。好比systrace這個東西,上述文章我只用來檢查了卡頓掉幀的狀況,可是它其實還能夠 查看CPU調度狀況和CPU多核分配狀況,還能夠檢查主線程的線程狀態切換狀況等。

請查看完整的PDF版
(更多完整項目下載。未完待續。源碼。圖文知識後續上傳github。)
能夠點擊關於我聯繫我獲取983頁完整PDF
(VX:mm14525201314)

image

相關文章
相關標籤/搜索