在最近的一次項目開發中
我遇到了
Adreno-GSL: <gsl_memory_alloc_pure:2258>: GSL MEM ERROR: kgsl_sharedmem_alloc ioctl failed.
最終:
OpenGLRenderer: GL error: Out of memory!
OpenGLRenderer: glViewport error! GL_OUT_OF_MEMORY (0x505)
實現了這些 ...
其主要原因是項目中需要使用到Webview來開發。Webview的確是一個很強大的東西,使用它開發後,我客戶端的代碼量少了很多很多。不過WebView的使用也是存在很多問題的。其中問題比較大的就是硬件加速的問題吧。在Android 3.0版本以上,都使用了硬件加速,不可否認,使用硬件加速的確帶來了很多好處,就如,瀏覽的流暢度很不錯。但是它也帶來了一些問題。
在Android 4.0的某些設備上,在View
刷新時會出現花屏和屏幕上的某些View錯位的現象。 經過調查後發現adb logcat
中出現很多OpenGLRenderer: 0x501
的錯位:
10-06 11:34:39.090: DEBUG/OpenGLRenderer(3104): GL error from OpenGLRenderer: 0x501
10-06 11:34:39.386: DEBUG/OpenGLRenderer(3104): GL error from OpenGLRenderer: 0x501
10-06 11:34:39.656: DEBUG/OpenGLRenderer(3104): GL error from OpenGLRenderer: 0x501
從這個日誌,初步懷疑是硬件加速導致的問題。 經過分析發現使用了比較複雜的自定義View
,可能會導致硬件加速渲染出錯.
硬件加速的優點與缺點
硬件加速能使用GPU來加速2D圖像的渲染速度,但是硬件加速並不能完全支持所有的渲染操作, 針對自定義的View,硬件加速可能導致渲染出現錯誤。 如果有自定義的View,需要在硬件加速的設備上進行測試,如果出現渲染的問題,需要關閉硬件加速。
開啓和關閉硬件加速
對硬件加速的開關可以在不同的級別進行控制:
- Application
- Activity
- Windows
- View
Application級別
在Applciation級別控制硬件加速的開關:
<application android:hardwareAccelerated="true" ...>
Activity級別
可以對單個的Activity
控制是否啓用硬件加速:
<application android:hardwareAccelerated="true">
<activity ... />
<activity android:hardwareAccelerated="false" />
</application>
Window級別
getWindow().setFlags(
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
View級別
在指定的View上關閉硬件加速:
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
或者使用android:layerType="software"
來關閉硬件加速:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingLeft="2dp"
android:layerType="software"
android:paddingRight="2dp" />
如何判斷一個View是否啓用了硬件加速
View.isHardwareAccelerated()
returns true if the View is attached to a hardware accelerated window.Canvas.isHardwareAccelerated()
returns true if the Canvas is hardware accelerated
而小翊的問題就是在主頁面的Recycler因爲是自定義的View,無意間開啓了硬件加速,當然還有一些其他原因的內存泄漏點...
而我的Recycler中的item又都是以高清圖片爲主,因爲我在全局開啓了硬件加速導致的瘋狂繪製,最後就在瘋狂(繪製View)的時候導致OOM...
可參考官方文檔:http://developer.android.com/guide/topics/graphics/hardware-accel.html
硬件加速技術分析:https://blog.csdn.net/coloriy/article/details/74395236