Android 性能優化之旋轉屏幕優化

我的博客原文地址

問題背景

在桌面轉屏發現響應不夠迅速,對比其他產品有很大的提升空間,針對此問題進行了一些分析和優化。

問題分析和解決方法

首先簡單介紹一下旋轉屏幕的流程,首先各個界面要進行重繪,在重繪過程中要進行凍屏,只有所有Window都進行繪製完成了才進行轉屏,因此這裏面就有個木桶效應,轉屏的時間取決於重繪最慢的那個。
首先分析Log,找出可以優化的點:

adb shell dumpsys window -d enable 10
adb logcat -v threadtime -s WindowManager | grep -E "Screen frozen for|Dismissing screen|Orientation start waiting for draw|Orientation not waiting for draw"

adb shell dumpsys window -d enable 10是使能DEBUG_ORIENTATION,開啓打印轉屏相關的Log。

WindowManager: Orientation start waiting for draw mDrawState=DRAW_PENDING in Window{249e41f u0 StatusBar}, surface Surface(name=StatusBar)
WindowManager: Orientation start waiting for draw mDrawState=DRAW_PENDING in Window{731dc6a u0 com.android.launcher/com.android.launcher.Launcher}, surface Surface(name=com.android.launcher/com.android.launcher.Launcher)
WindowManager: Orientation start waiting for draw mDrawState=DRAW_PENDING in Window{b22eda5 u0 com.android.systemui.ImageWallpaper}, surface Surface(name=com.android.systemui.ImageWallpaper)
WindowManager: Orientation start waiting for draw mDrawState=DRAW_PENDING in Window{731dc6a u0 com.android.launcher/com.android.launcher.Launcher}, surface Surface(name=com.android.launcher/com.android.launcher.Launcher)
WindowManager: Orientation start waiting for draw mDrawState=DRAW_PENDING in Window{731dc6a u0 com.android.launcher/com.android.launcher.Launcher}, surface Surface(name=com.android.launcher/com.android.launcher.Launcher)
WindowManager: Orientation start waiting for draw mDrawState=DRAW_PENDING in Window{94517ed u0 com.android.launcher/com.android.launcher.Launcher}, surface Surface(name=com.android.launcher/com.android.launcher.Launcher)
WindowManager: Orientation not waiting for draw in Window{94517ed u0 com.android.launcher/com.android.launcher.Launcher}, surface Surface(name=com.android.launcher/com.android.launcher.Launcher)
WindowManager: Orientation not waiting for draw in Window{b22eda5 u0 com.android.systemui.ImageWallpaper}, surface Surface(name=com.android.systemui.ImageWallpaper)
WindowManager: Orientation not waiting for draw in Window{249e41f u0 StatusBar}, surface Surface(name=StatusBar)
WindowManager: Screen frozen for +968ms due to Window{249e41f u0 StatusBar}
WindowManager: **** Dismissing screen rotation animation

通過Log發現,轉屏是要等StatusBarLauncherImageWallpaper繪製完纔會開始的。
根據Screen frozen for +968ms due to Window{249e41f u0 StatusBar}發現目前的瓶頸在狀態欄這裏,首先分析一下狀態欄的代碼,可以藉助於 TraceView 工具迅速定位到耗時較多方法的位置,發現在NotificationPanelViewonConfigurationChanged函數中有一項耗時的操作,先進行這部分優化。
然後看效果:

WindowManager: Screen frozen for +747ms due to Window{3aaa434 u0 com.android.launcher/com.android.launcher.Launcher}

發現這個時候瓶頸已經不再StatusBar這裏了,接下面再優化Launcher就可以。
接下來看看ImageWallpaper是不是有優化的餘地呢?
通過 TraceView 工具發現在ImageWallpaper.drawFrame()方法中,每次旋轉屏幕都會在updateWallpaperLocked()中調用mWallpaperManager.getBitmap()進行解碼圖片,這個也是沒有必要的,只初始化一次就可以了,可以進行如下的修改:

                // Load bitmap if it is not yet loaded or if it was loaded at a different size
                if (mBackground == null/* || surfaceDimensionsChanged*/) {

只在mBackgroundnull是加在壁紙圖片。
第三步的任務就是優化Launcher了,此處的優化點各不相同,而且較多,就不一一介紹了。

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