發現自己的手機上某個介面出現了花屏,某些控制項背景被展開過多遮住了其他控制項,很難看。這種現象高機率出現,分析了下發現:一旦發生這種現象,必然會列印下面這種log,google了下,這種log應該是硬體加速引入的。在從view層級關閉了硬體加速開關之後,問題沒有再出現。
[plain]
D/OpenGLRenderer(10887): GL error from OpenGLRenderer: 0x501
E/OpenGLRenderer(10887): GL_INVALID_VALUE
D/OpenGLRenderer(10887): GL error from OpenGLRenderer: 0x501
E/OpenGLRenderer(10887): GL_INVALID_VALUE 硬體加速開關是android3.0開始引入的,大致有個印象,但是我們代碼中並沒有開啟過硬體加速開關。自己寫了個demo,log顯示硬體加速開關確實已經被開啟。看來是google做了些什麼,去官方文檔上看了看,有下面一句話:
Beginning with Android 4.0, hardware acceleration for all windows is enabled by default if your application has set either targetSdkVersion or minSdkVersion to “14" or higher.
到這裡,硬體加速開關開啟的原因找到了,為什麼在這個應用的這個介面才會引入問題呢。
先學習下android硬體加速的一些概念再說。android自3.0引入了硬體加速,即使用GPU進行繪圖,旨在得到更加平滑的動畫更加平滑滾動,和更好的總體效能和響應使用者的互動。但是硬體加速並不能完善的支援所有的繪圖,通常表現為內容不可見,異常或渲染錯誤。一般出現了問題,就需要關閉硬體加速開關。為了方便控制硬體加速開關,android在四個層面提供了支援:
1.Application level:在AndroidManifes檔案中給application標籤增加如下配置語句,即可開啟硬體加速開關,這個開關對整個應用起作用。
[html]
<application android:hardwareAccelerated="true" ...>
<application android:hardwareAccelerated="true" ...>2.Activity level:同樣還是在AndroidManifes檔案中,給activity標籤增加如下配置語句,即可關閉硬體加速開關,這個開關對當前activity起作用,可以覆蓋1中的application開關:
[html]
<application android:hardwareAccelerated="true">
<activity ... />
<activity android:hardwareAccelerated="false" />
</application>
<application android:hardwareAccelerated="true">
<activity ... />
<activity android:hardwareAccelerated="false" />
</application>3.Window level:在代碼中增加下面代碼,即可在視窗層級開啟硬體加速開關。注意在視窗層級,只能開啟硬體加速開關,不能關閉,不同上面1,2。
[html]
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);4.View level:在代碼中給view設定如下屬性,即可從view層級關閉硬體加速開關。在這裡只能關閉硬體加速開關,不能開啟。這個層面決定權是最高的,可以覆蓋上面三個層級。
[html]
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 到這裡還是不清楚為什麼只有這個介面的view發生了問題。這個view不是應用覆蓋重寫的,並不複雜。看了下google後面提供的一些高效使用硬體加速開關的技巧:
Reduce the number of views in your application
Avoid overdraw
Don't create render objects in draw methods
Don't modify shapes too often
Don't modify bitmaps too often
後來開啟android開發人員選項的檢查是否過度繪製的功能,發現這個介面有很明顯的過度繪製。到這裡基本可以得出,這個介面由於開啟硬體加速器高機率出現花屏,應該是違反了第二條:Avoid overdraw。去看了下google的Android Drawing Models說明,還是沒有從根本上弄清楚硬體加速是怎麼一個回事。沒有從代碼上看到這些總是感覺不太清楚,不過對於硬體加速瞭解到這裡已經足夠解決開發過程中遇到的問題。最後補充說明在分析上述的花屏問題時,發現將.9圖片去掉換成普通資源,該問題也會得到修正。