Android性能優化-過渡繪製解決方案

2021-03-02 鴻洋

本文作者:libraryboy

libraryboy的博客地址:

http://blog.csdn.net/a740169405


屏幕上某一像素點在一幀中被重複繪製多次,就是過渡繪製。 
下圖中多個卡片跌在一起,但是只有第一個卡片是完全可見的。背後的卡片只有部分可見。但是Android系統在繪製時會將下層的卡片進行繪製,接著再將上層的卡片進行繪製。但其實,下層卡片不可見的部分是不需要進行繪製的,只有可見部分才需要進行繪製。 


依據過渡繪製的層度可以分成: 


- 無過渡繪製(一個像素只被繪製了一次) 
- 過渡繪製x1(一個像素被繪製了兩次) 
- 過渡繪製x2(一個像素被繪製了三次) 
- 過渡繪製x3(一個像素被繪製了四次) 
- 過渡繪製x4+(一個像素被繪製了五次以上)

方法一:通過開發者選項開啟GPU過渡繪製調試 

Android手機的開發者選項中有『調試 GPU 過度繪製』的選項: 

點開後後選擇『顯示過渡繪製區域』: 


方法二:通過adb命令開啟GPU過渡繪製調試 


當然,如果每次都進入系統設置嫌麻煩,可以使用adb命令進行開啟和關閉: 
開啟『調試 GPU 過度繪製』:

adb shell setprop debug.hwui.overdraw show

關閉『調試 GPU 過度繪製』:

adb shell setprop debug.hwui.overdraw false

執行命令之後可能需要重新啟動你當前開發的應用。

顏色與過渡繪製:

原色:沒有過度繪製

藍色:1 次過度繪製

綠色:2 次過度繪製

粉色:3 次過度繪製

紅色:4 次及以上過度繪製

在平時的開發中,如果出現粉色及以上的過渡繪製情況。說明過渡繪製以及很嚴重了。需要進行優化。


1. 去除Activity自帶的默認背景顏色: 


查看Android源碼裡的Theme主題,如下:


也就是說繼承Theme這個style的風格,默認情況下,新建一個Activity都是有背景的。正常情況下,很多界面其實是不需要背景的。

下面是華為自帶天氣APP的首頁,我們可以看到文字部分以及圖標部分都是綠色,說面已經是第三層過渡繪製了,其中背後天氣圖是一層,文字又是一層,正常來說應該只有兩層,也就是文字和圖標應該是藍色。

那麼這多出來的一層應該就是Activity自帶的背景色了。也就是theme裡面設置的。 


我們只要在自己的AppTheme裡面去除該背景色即可:

<style name="AppTheme" parent="android:Theme.Light.NoTitleBar">    <item name="android:windowBackground">@null</item></style>

或者在Activity的onCreate方法中:

getWindow().setBackgroundDrawable(null);

2.使用Canvas的clipRect和clipPath方法限制View的繪製區域 

一個Activity對應有一個Canvas,也就是畫布,畫布的概念就是一個畫板,這個畫布提供了很多的API,我們可以通過調用畫布的API來繪圖以及對畫布做一些操作,clipRect方法用來裁切畫布上的一個矩形區域,該矩形區域用Rect對象來描述。調用了clipRect之後,畫布的可繪製區域減小到和Rect指定的矩形區域一樣大小。所有的繪製將限制在該矩形範圍之內。這裡的裁切概念和PS裡的裁切類似。

典型的例子,抽屜布局,找了網易雲音樂開刀:

 
 


注意觀察左側抽屜打開的時候,抽屜布局和背後布局重疊在一起了,此時整個屏幕一多半都變成了紅色,過渡繪製嚴重。

在抽屜布局彈出時,抽屜布局是不透明的,也就是說抽屜布局背後擋住的內容布局是不需要繪製的,而網易雲進行了繪製,導致抽屜布局所在區域的像素點繪製了多次。

google官方在android.support.v4.widget包下有DrawerLayout.Java類。使用來實現抽屜布局的。該類在重寫了drawChild方法:


drawChild方法在ViewGroup類的dispatchDraw方法內被調用,用來繪製子視圖,DrawerLayout類通過重寫該方法,因為在所有孩子視圖繪製之前都會調用drawChild方法,但是這裡只需要對內容區域視圖做裁切,當繪製內容區域視圖時,取得抽屜視圖的位置信息,如果抽屜視圖可見、背景為不透明、抽屜高度和父布局高度一致時,取得抽屜視圖左、上、右、下邊緣在canvas中的位置信息。接著進行裁切,將內容視圖未被擋住的部分區域裁切出來,並把裁切完的canvas交由子View進行繪製,這樣,內容區域只有在裁切後的區域才會繪製,其他區域不進行繪製。

待子View繪製完之後,恢復Canvas到裁切之前的狀態,因為一個Window下的所有View都使用的是同一個Canvas,所以需要恢復狀態給其他子View使用。

下面看一個系統裡的「下載」APP,使用的是DrawerLayout實現: 


 

 
應用中雖然內容區域是紅色,但是抽屜視圖拉出來之後,抽屜視圖的過渡繪製情況卻比內容區域未被擋住的部分少。

3. ImageView的background和imageDrawable重疊 


Android中,所有的view均可以設置background。ImageView除了能夠設置background之外,還能設置ImageDrawable。

在開發中,很多時候需要顯示圖片,在圖片加載出來之前通常是需要顯示一張默認圖片的,很多時候會使用ImageView的background屬性來設置默認背景圖,而imageDrawable來設置需要加載的圖片。這樣會導致一個問題,當圖片加載到頁面後,默認背景圖被擋住了,但是卻任然需要繪製,導致過渡繪製情況的發生。

解決方案是把背景圖和真正加載的圖片都通過imageDrawable方法進行設置。


Android中一個window對應一個Canvas,window下的所有視圖(View/ViewGroup)使用的都是同一個canvas,視圖樹的父節點在調用子視圖的View.draw之前,會對Canvas進行裁切,裁切的區域就是View在屏幕中所佔的矩形區域,這也就是為什麼超過View邊界的內容會被裁切掉的原因。

既然過渡繪製值一個像素點被繪製多次,我們只要保證圖片或者背景顏色不要疊加在一起即可。正確的方式應該是儘量減少帶背景的View產生重疊區域。如果重疊,使用canvas的clipRect進行裁切。

儘量減少視圖的深度,來減少視圖樹的遍歷過程。

如果你有好的文章想和大家分享歡迎投稿,直接向我投遞文章連結即可。

歡迎長按下圖->識別圖中二維碼或者掃一掃關注我的公眾號:

相關焦點

  • 那些 Android 程式設計師必會的視圖優化策略
    概述現在的APP一些視覺效果都很炫,往往在一個界面上堆疊了很多視圖,這很容易出現一些性能的問題,嚴重的話甚至會造成卡頓。因此,我們在開發時必須要平衡好設計效果和性能的問題。本文主要講解如何對視圖和布局進行優化:包括如何避免過度繪製,如何減少布局的層級,如何使用ConstraintLayout等等。2. 過度繪製(Overdraw)2.1 什麼是過度繪製?
  • Android性能優化之APK瘦身詳解(瘦身73%)
    基於這種快速開發的現狀,我們app優化前已經有87.1M了,包大了,運營說這樣轉化不高,只能好好搞一下咯。優化過後包大小為23.1M(優化了73%,不要說我標題黨)。好了好了,我要闡述我的apk超級無敵魔鬼瘦身之心得了。文章主要內容從理論出發,再做實際操作。分為下面幾個方面:1. 結構分析, 2.具體實操 3. 總結 4. 參考資料1.
  • 找出卡頓的元兇 —— 渲染性能優化
    撕裂的圖像屏幕撕裂(Tear)的問題,早在 PC 遊戲時代就被發現, 並不停的在嘗試進行解決。其中最知名可能也是最古老的解決方案就是 VSYNC 技術。,可以找到下面幾個選項:調試 GPU 過度重繪(Debug GPU overdraw)我們可以通過手機設置裡面的 開發者選項 ,打開 顯示過渡繪製區域(Show GPU Overdraw)的選項,可以觀察 UI 上的 Overdraw 情況。
  • android app殺死啟動專題及常見問題 - CSDN
    所以相應的優化方案:減少 onCreate方法的工作量。不要讓Application參與業務邏輯。不要在Application中做耗時操作,一些初始化操作可以開啟子線程來完成。不要以靜態變量方式在Application中保存數據。
  • 用戶說 阿里百川HotFix解決方案使用體驗
    ,什麼androidfix,還有什麼其他的,這個就不囉嗦了。過了一個G20,偶爾逛了一下阿里百川,發現百川發布的一個sdk,於是懷抱著期待來到這裡分享一下使用阿里百川的hotfix解決方案中的一些梗。首先分享一下阿里百川hotfix解決方案,這個sdk是基於andfix方案的一個擴展,對於andfix進行一些優化,極大的方便了我們的使用,如果順利的話可能幾個小時就可以解決熱修補的問題,當然先關機型的不支持也再所難免,誰讓android這麼開放呢!目前這個SDK還在公測中,或許會有一些bug,但是總比自己費力的構造要好的多,所以,果斷選擇。
  • 開源 | Scene:Android 開源頁面導航和組合框架
    開發背景西瓜視頻面臨的問題西瓜視頻在 1.0.8 版本有做過一次播放體驗的優化,希望首頁正在播放的短視頻跳轉到詳情頁面時,能夠有一個平滑的動畫過渡。下面的視頻是老版本的過度效果:下面的視頻是新版本的過度效果:這種複雜的過渡動畫,是不可能拿 Activity 實現的。
  • Google官方 詳解 Android 性能優化【史詩巨著之內存篇】
    明雲(張明雲),知乎專欄上寫了一系列的性能優化,都相當實用,open dev也會定期送上乾貨,不定期匯總推薦當下優秀文章)今天來看下楊超凡授權本公眾號的Google官方的性能優化一些優化建議:點擊閱讀原文,可查看楊超凡的原文:http://blog.csdn.net/chivalrousman/article/details/51553114,話不多說,看下正文。
  • 裴琳 · 微成長--web性能優化與前端工程
    我們有雅虎14條性能優化原則,還有兩本很經典的性能優化指導書:《高性能網站建設指南》、《高性能網站建設進階指南》。這些性能優化原則大概是在7年前提出的,對於web性能優化至今都有非常重要的指導意義。因此在前端工程界,總會看到周期性性能優化工作,辛勤的前端工程師每到月圓之夜就會傾巢出動根據優化原則做一次性能優化。|性能優化是一個工程問題本文將從一個全新的視角來思考web性能優化與前端工程之間的關係,揭示前端性能優化在前端架構及開發工具設計層面的實現思路。
  • Android 性能優化實戰 - 界面卡頓
    由於性能優化涉及的知識點比較多,我一時半會也無法徹底回答。恰好之前在做需求時也遇到了一個卡頓的問題,因此今晚寫下這篇卡頓優化的文章,希望對大家有所幫助。先來看看卡頓的現象:1.高斯模糊算法分析把耗時操作放到子線程中去處理,的確解決了界面卡頓問題。但這其實是治標不治本,我們發現圖片加載處理異常緩慢,內存久高不下有時可能會導致內存溢出。接下來我們來分析一下高斯模糊的算法實現:
  • Android TV開發簡介
    下面的例子展示了一個基本的AndroidMainifest:<application  android:banner="@drawable/banner" >  ...  <activity    android:name="com.example.android.MainActivity"    android:label="@string/app_name" >    <intent-filter>      <action android:name="android.intent.action.MAIN" />      <
  • Thundercomm創通聯達交鑰匙解決方案
    為了滿足行業需求,Thundercomm創通聯達基於高通SDW 2500可穿戴晶片平臺,推出了Thundercomm TurboX 2500解決方案。技術型分銷商Excelpoint世健公司負責Thundercomm創通聯達的產品經理表示:「TurboX 2500是一種端到端解決方案,包括雲服務、智慧型手機App和終端設備。
  • 實現unity級聯陰影的過渡和屏幕空間改善shadowmap漏光!
    實現unity 級聯陰影的過渡需求場景的shadowmap 精度勉強滿足場景物件的需求,但對於近距離角色的小掛件投影 衣服厚度 領子等投影精度是不足的。雖然獨佔的shadowmap可以實現,但為了不增加開銷我嘗試了用級聯陰影的最近1級做角色陰影。這樣操作很簡單不值得寫這篇內容,但這樣做需要解決2個級聯接縫問題。
  • 項目主程分享13人演出的實現與優化方案
    在上個月,Unity在日本舉辦了「Unite Tokyo 2018」技術分享大會,期間《偶像大師MLTD》開發團隊,萬代南夢宮工作室的主程序池田早人、程式設計師加藤政樹分享了他們的製作經驗,以及遇到各種優化問題時的解決方案。
  • Android屬性動畫:這是一份全面 & 詳細的核心使用類ObjectAnimator學習攻略
    ="http://schemas.android.com/apk/res/android" android:valueFrom="1" // 初始值 android:valueTo="0" // 結束值 android:valueType="floatType" // 變化值類型 :floatType & intType
  • GitHub Top 100的Android開源庫
    ZXingZXing 是二維碼領域中名氣最大的開源項目, 它提供了多個平臺的二維碼/條形碼掃描解決方案, 擁有掃描快, 識別率高, 使用簡單等特點13.Material-AnimationsMaterial-Animations 是一個很好過渡動畫庫, 可以應用於 Activity 與 Activity 之間的跳轉, Fragment 與 Fragment 之間的跳轉, 以及各個 View 變化前後的過渡動畫36.
  • 直播App中Android酷炫禮物動畫實現方案(下篇):SVGA由來與Lottie的對比
    使用A-PNG可以完美地解決效果差的問題,因為PNG支持32位顏色啊,但是,同樣的天使動畫,大小可以達到9M,播放資源佔用更更更高!探索那麼,有沒有更好的方法去解決以上的問題?其實是有的,早在2015年,Adobe就已經把CreateJS收歸旗下,並且可以完美地將Flash動畫導出至Web中。
  • 直播App中Android酷炫禮物動畫實現方案(上篇)
    從開發人員的角度來看,這樣的效果雖然漂亮,實現但卻是一大挑戰,除了要考慮編碼實現的效率、性能表現外,還要結合直播業務本身的特性等。實現思路首先,從實現思路方面入手,有以下幾個方案作為考慮:從實現性能、效率以及復用角度上來看,我們最終採用了最後一種方案。
  • Android Studio 4.0 發布
    開發者不再需要創建和修改複雜的 XML 文件,Motion 編輯器會生成,同時還支持編輯約束集、過渡、關鍵幀和視圖屬性。並且,此前已經使用了ConstraintLayout的項目,IDE 可以輕鬆地將其轉換為MotionLayout。
  • Android安全防護之旅---幾行代碼讓Android應用變得更加安全
    關於解決這種反調試方案後面再說。不過這種方式也不是萬能的,後面會介紹如何解決這種反調試問題。但是這種方式不是萬能的,後面會介紹如何解決這種反調試問題。當然這裡還有一種方案,就是可以檢查進程列表中有沒有android_server進程,不過這種方式都不是萬能的,後面會詳細介紹如何解決這種反調試方案。
  • 伺服性能優化神器 —— 波特圖
    振幅(dB)和相位(度)的測量值繪製在所測試頻率範圍的對數刻度上。這些圖表顯示了機械系統對頻率範圍的響應情況。振幅和相位會根據機構的設計,按照特定模式發生變化,然後通過該模式,我們可獲得系統相關信息。共振點為如何通過系統調優來優化系統提供了線索。