常用 Android 開發者選項與卡頓原因

應用UI卡頓

常見原因主要在以下幾個方面:

1、人爲在UI線程中做輕微耗時操作,導致UI線程卡頓;

2、佈局Layout過於複雜,無法在16ms內完成渲染;

3、同一時間動畫執行的次數過多,導致CPU或GPU負載過重;

4、View過度繪製,導致某些像素在同一幀時間內被繪製多次,從而使CPU或GPU負載過重;

5、View頻繁的觸發measure、layout,導致measure、layout累計耗時過多及整個View頻繁的重新渲染;

6、內存頻繁觸發GC過多(同一幀中頻繁創建內存),導致暫時阻塞渲染操作;

7、冗餘資源及邏輯等導致加載和執行緩慢;

發現和定位問題,及解決方案:
打開GPU繪製,手指在卡片上來回滑來滑去,通過觀察高線的位置判斷卡頓的時機,我們發現滑動停止後再一次滑動時出現高峯,如圖,按照經驗ViewPager的卡頓問題在於滑動事件的回調,重點排查onPageScrolled,onPageSelected及Adapter的instantiateItem方法。

參考:

ViewPager卡頓優化實戰

開發者選項:

Android 開發者選項能夠幫助我們定位開發中遇到的問題,輔助我們瞭解應用的性能問題,對提升開發和優化效率大有幫助。

Stay awake (不鎖定屏幕)

充電時保持屏幕喚醒,開發的時候,時不時的鎖屏真是夠了,開啓它後只要插着USB線就不需要總去解鎖屏幕啦。

Process Stats (進程統計信息)

使用場景: 查看後臺進程和資源佔用,以圖形的方式展示了後臺運行的進程,以及相應的運行時間和內存佔用。

使用說明: 如圖,左上角是指其統計的時間範圍,而其下面的條形區域的進度顏色則顯示了當前內存使用的情況,綠色表示處於正常範圍,黃色則表示有些緊張,紅色則是告急狀態。再下面的列表區域則顯示了當前運行的進程,右上方的百分比標明其在這段時間內運行的相對時間,100% 就表示其在這段時間內都在運行。點擊進入,能夠看到起內存佔用詳細信息。

在圖中,分別顯示了內存(RAM)佔用情況,以及運行的 Services 列表。

Show layout bounds (顯示佈局邊界)

使用場景: 查看 view 的區域,以及相應的 margin 和 padding.

使用說明: 開啓後就能看到效果.

紅色線:一個view的上邊,下邊,左邊,右邊 邊界線
藍色直角:一個view的角,比如長方形的四個角
粉紅色塊:margin系列的,比如layout_marginLeft 、layout_marginBottom
(注意:padding系列的,沒有邊界線,也沒有顏色,不容易看出來)
觀察佈局邊界線,有助於我們在佈局的時候,不知道控件在哪裏,不知道控件的具體位置的,可以明確的看到我們的控件在哪裏。還有助於我們準確的佈局控件
有時候出現一些空白空隙,或者控件重疊的情況,打開佈局邊界,一看就明白了。

Debug GPU OverDraw (調試 GPU 過度繪製)

先來看看什麼是過度繪製。我們在繪製界面的時候,往往會有多個層級,例如在一塊白色背景上繪製了一張圖片,但圖片下面遮住的白色背景是我們所看不到的,這一部分也是不需要繪製的,我們稱這種現象爲 過度繪製。顯然,過度繪製造成了額外的工作,是我們應該儘可能地避免的問題。

使用場景: 查看開發的 APP 是否存在很嚴重的過度繪製問題。

使用說明: 開啓後就能看到效果,選擇 Debug GPU OverDraw, 並勾選 Show overdraw areas。


沒有顏色: 意味着沒有overdraw。像素只畫了一次。
藍色: 意味着overdraw 1倍。像素繪製了兩次。大片的藍色還是可以接受的(若整個窗口是藍色的,可以擺脫一層)。
綠色: 意味着overdraw 2倍。像素繪製了三次。中等大小的綠色區域是可以接受的但你應該嘗試優化、減少它們。
淺紅: 意味着overdraw 3倍。像素繪製了四次,小範圍可以接受。
暗紅: 意味着overdraw 4倍。像素繪製了五次或者更多。這是錯誤的,要修復它們。

藍色,淡綠,淡紅,深紅代表了4種不同程度的Overdraw情況,我們的目標就是儘量減少紅色Overdraw,看到更多的藍色區域。

值得提醒的是,過度繪製有時是無法避免的,Android建議是不要超過一次過度繪製,也就是可以是藍色的,不能綠了。

Profile GPU rendering(GPU 呈現模式分析)

使用場景: 如我們所知,如果一陣的繪製時間超過了 16 ms,那麼用戶就能實際地感受到視覺上的差異,這也就是我們常說的卡頓。
GPU 呈現模式能使得我們以圖形化的方式查看繪製每一幀花費的時間,以及其是否超過 16 ms,在這種模式下,可以比較粗略地定位在那一塊操作比較卡頓。我們分析下圖片,圖片中有很多豎着的線,這些豎着的線表示一幀,其中豎線的每個顏色都表示着這一陣在繪製中的某個步驟,高度就是其花費的時間。上方的這個橫線,表示16ms,任何一根豎着的線都可以和 16ms 進行比較,如果其超過 16ms,那麼它的繪製時間就超過了建議的時間範圍,會造成界面卡頓。開發者可以通過查看進行什麼操作會使得豎線高度飆升,來初步定位卡頓問題。

使用說明: 點擊 Profile GPU rendering, 選擇 On screen as bars.

隨着界面的刷新,界面上會滾動顯示垂直的柱狀圖來表示每幀畫面所需要渲染的時間,柱狀圖越高表示花費的渲染時間越長。

中間有一根綠色的橫線,代表16ms,我們需要確保每一幀花費的總時間都低於這條橫線,這樣才能夠避免出現卡頓的問題。

每一條柱狀線都包含三部分,藍色代表測量繪製Display List的時間,紅色代表OpenGL渲染Display List所需要的時間,黃色代表CPU等待GPU處理的時間。

每列數據顯示了渲染每一幀需要的時間,每一條線意味着一幀被繪製出來,而每條線中的不同顏色又代表着在繪製過程中的不同階段:
Draw (藍色) 代表着View.onDraw()方法。在這個環節會創建/刷新DisplayList中的對象,這些對象在後面會被轉換成GPU可以明白的OpenGL命令。而這個值比較高可能是因爲view比較複雜,需要更多的時間去創建他們的display list,或者是因爲有太多的view在很短的時間內被創建。
Process (紅色) – 執行Display list中的內容並創建OpenGL命令。如果有過多或者過於複雜的display list需要執行的話,那麼這階段會消耗較長的時間,因爲這樣的話會有很多的view被重繪。而重繪往往發生在界面的刷新或是被移動出了被覆蓋的區域。
Execute (黃色) – 發送OpenGL命令到GPU。這個階段是一個阻塞調用,因爲CPU在這裏只會發送一個含有一些OpenGL命令的緩衝區給GPU,並且等待GPU返回空的緩衝區以便再次傳遞下一幀的OpenGL命令。而這些緩衝區的總量是一定的,如果GPU太過於繁忙,那麼CPU則會去等待下一個空緩衝區。所以,如果我們看到這一階段耗時比較長,那可能是因爲GPU過於繁忙的繪製UI,而造成這個的原因則可能是在短時間內繪製了過於複雜的view。

CPU無法直接將命令發給GPU 首先要明白,GPU要繪製什麼樣的視圖是需要CPU發出指令的,但CPU不會直接告訴GPU怎麼做,而是會先將這一命令存入一個“盒子”,在盒子中會形成一個列表,然後GPU從盒子中取出命令進行視圖的渲染繪製。

明白了上面的過程,下面就該說說圖中不同顏色到底代表了什麼含義。

紅色代表了“執行時間”,它指的是Android渲染引擎執行盒子中這些繪製命令的時間,假如當前界面的視圖越多,那麼紅色便會“跳”得越高。實際使用中,比如我們平時刷淘寶App時遇到出現多張縮略圖需要加載時,那麼紅色會突然跳很高,但是此時你的頁面滑動其實是流暢的,雖然等了零點幾秒圖片才加載出來,但其實這可能並不意味着你卡住了。

黃色通常較短,它代表着CPU通知GPU“你已經完成視圖渲染了”,不過在這裏CPU會等待GPU的回話,當GPU說“好的知道了”,纔算完事兒。假如橙色部分很高的話,說明當前GPU過於忙碌,有很多命令需要去處理,比如Android淘寶客戶端,紅色黃色通常會很高。

藍色。假如想通過玄學曲線來判斷流暢度的話,其實藍色的參考意義是較大的。藍色代表了視圖繪製所花費的時間,表示視圖在界面發生變化(更新)的用時情況。當它越短時,即便是體驗上更接近“絲滑”,當他越長時,說明當前視圖較複雜或者無效需要重繪,即我們通常說的“卡了”。
理解了玄學曲線不同顏色代表的意義,看懂玄學曲線就不難了。一般情況下,當藍色低於綠線時都不會出現卡頓,但是想要追求真正的絲般順滑那當然還是三色全部處於綠線以下最爲理想。

參考:Android開發者選項——Gpu呈現模式分析

綠色的橫線表示每一幀渲染時間的閾值,值爲16ms,這是因爲Android流暢運行的幀率爲60fps,如果每一幀的渲染時間超過16ms,幀率就降低到小於60fps,會出現丟幀的情況,直觀的感受就是頁面出現卡頓。如果發現條形圖基本上低於綠色的線,說明頁面的繪圖效率良好,但當條形線頻繁的超過綠色的線,應用的佈局應該是有問題的,通常都是由於佈局不合理或者是太過複雜。通過不同顏色的線所佔的比重,可以確定卡頓是由哪個階段引起的。

每種顏色代表每一幀渲染過程中需要完成的某一件事情,因爲6.0之前的三種顏色不大能夠清晰地幫助我們定位性能問題的具體原因,所以從6.0開始,將每一幀的渲染過程拆分成了8個步驟,每個步驟一種顏色,每種顏色的.

含義如下:

(1)Swap Buffers:表示處理任務的時間,也可以說是CPU等待GPU完成任務的時間,線條越高,表示GPU做的事情越多;
(2)Command Issue:表示執行任務的時間,這部分主要是Android進行2D渲染顯示列表的時間,爲了將內容繪製到屏幕上,Android需要使用Open GL ES的API接口來繪製顯示列表,紅色線條越高表示需要繪製的視圖更多;
(3)Sync & Upload:表示的是準備當前界面上有待繪製的圖片所耗費的時間,爲了減少該段區域的執行時間,我們可以減少屏幕上的圖片數量或者是縮小圖片的大小;
(4)Draw:表示測量和繪製視圖列表所需要的時間,藍色線條越高表示每一幀需要更新很多視圖,或者View的onDraw方法中做了耗時操作;
(5)Measure/Layout:表示佈局的onMeasure與onLayout所花費的時間,一旦時間過長,就需要仔細檢查自己的佈局是不是存在嚴重的性能問題;
(6)Animation:表示計算執行動畫所需要花費的時間,包含的動畫有ObjectAnimator,ViewPropertyAnimator,Transition等等。一旦這裏的執行時間過長,就需要檢查是不是使用了非官方的動畫工具或者是檢查動畫執行的過程中是不是觸發了讀寫操作等等;
(7)Input Handling:表示系統處理輸入事件所耗費的時間,粗略等於對事件處理方法所執行的時間。一旦執行時間過長,意味着在處理用戶的輸入事件的地方執行了複雜的操作;
(8)Misc Time/Vsync Delay:表示在主線程執行了太多的任務,導致UI渲染跟不上vSync的信號而出現掉幀的情況;

強制進行GPU渲染

這個選項的意思就是強制開啓硬件加速。對於用戶來講,開啓之後應用會變得流暢,但是由於有些Canvas方法不支持硬件加速,開啓之後可能會引起應用crash。

Don’t keep activities : 不保留活動

開啓這個選項後,當你從Activity A跳轉到Activity B時,Activity A就會被立即銷燬,這一般用來模擬設備內存不足時後臺Activity被銷燬的場景,如果你的應用能做到開啓它時功能仍基本正常,說明代碼設計得比較合理,不同Activity之間的耦和很低,對於複雜業務的應用來說,能做到這點真心不容易。

開啓這個選項表示頁面切到後臺以後將會被系統銷燬,一般用來模擬設備內存不足時後臺Activity被銷燬的場景。我們可以用它來測試頁面重建的穩定性。如果你的應用在開啓它時功能基本正常,說明代碼設計得比較合理,代碼寫的足夠健壯。這個具體怎麼理解呢?

我們知道Activity有一個回調方法onSavedInstanceState()會在頁面被切到後臺時調用來保存頁面的狀態,如果頁面重新切回前臺而且已經被系統銷燬的情況下,系統會幫我們重建頁面,這個狀態通常是很難模擬的。開啓這個功能,就可以模擬這個情況,然後進行頁面狀態恢復的調試。也就是說,如果兩個Activity A啓動B,B啓動後系統銷燬了頁面A,從B頁面再切回來時將會白屏(或者黑屏)一下,這就是系統在重建我們的A頁面。如果我們對頁面恢復的處理不當,就有可能導致頁面的重建出現異常,因爲畢竟系統沒有智能到幫我們保存所有必要的數據,有些還是需要我們自己手動來保存的。我們在測試中發現,如果將B頁面的屬性設置爲透明,也就是設置主題爲android:theme=”@android:style/Theme.Translucent”,這時候系統並不會銷燬A頁面,那是因爲A頁面並沒有執行onStop()回調方法。

這個功能只是作爲調試輔助開啓比較合適,普通用戶開啓後將嚴重影響用戶體驗。

參考:

android 中的開發者選項

對於開發者來說,Android 的開發者選項裏有哪些實用的功能?

Android調試系列之開發者選項常用功能

常用 Android 開發者選項詳述

15個必知的Android開發者選項

Android手機的開發者選項 詳解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章