硬加速开、关引起的错误

时间:2023-01-01 23:58:34

错误日志:

java.lang.OutOfMemoryError: Failed to allocate a 157286412 byte allocation with 16777216 free bytes and 111MB until OOM

日志分析:

由该错误日志分析可得,该错误是内存溢出。

解决方案:

  • 打开清单文件,找到application标签;
  • 在application标签中加入如下语句:
        android:hardwareAccelerated="false"
android:largeHeap="true"
  • 问题解决。

引申:

  • 从Android3.0 (API level11)开始,Android的2D显示管道被设计得更加支持硬加速。硬加速使用GPU承担了所有在View的canvas上执行的绘制操作。
  • 启用硬加速最简单的方法是对整个应用启用硬件速。如果你的应用只使用标准的view和Drawable,全局启用硬加速将不会带来任何负面影响。然而,因为硬加速并不是被所有的2D绘制所支持,所以启用它时可能对你的自定义绘制产生影响。出现的问题经常是不可见的,也可能是异常,或错误地显示像素。
  • 为了避免这些问题,android提供在以下各级别上启用或禁止硬加速:

    • Application
      在你的manifest文件中,把以下属性添加到标签来对你的整个应用启用硬加速:
      <application android:hardwareAccelerated="true" ...>

    • Activity
      如果你的应用在全局启用硬加速时行为不正确,你可以对个别activity单独启用硬加速。欲在actvity级别启用或禁止硬加速,你可以对<activity>元素使用android:hardwareAccelerated属性。下面的例子在整个应用中启用了硬加速,但对一个activity禁止了硬加速:
      <application android:hardwareAccelerated="true">
      <activity... />
      <activityandroid:hardwareAccelerated="false" />
      </application>

    • Window
      如果你需要更高颗粒度的控制,你可以使用以下代码为一个window启用硬加速:
      getWindow().setFlags(
      WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
      WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

      注:现在还不能对window级别禁止硬加速。

    • View
      你可以在运行时使用以下代码禁止个别View硬加速:
      myView.setLayerType(View.LAYER_TYPE_SOFTWARE,null);
      注:当前你不能在View级别启用硬加速。View层有除禁止硬加速之外的其它功能。

判断View是否被硬加速的必要性:

了解一个应用是否启用硬件速是很有必要的,对那些自定义View之类的东西尤其重要。当在你的应用中做了一些不被最新管线所支持的自定义绘制时,这更加重要。

判断View是否被硬加速的方法:

有两种方法可以检查应用是否被硬加速:

  • View.isHardwareAccelerated()
    如果View附加到一个硬加速的window上就返回true。

  • Canvas.isHardwareAccelerated()
    如果Canvas被硬加速了就返回true。

注意:

如果你必须在意绘制的代码中做这个,应使用Canvas.isHardwareAccelerated()而不是View.isHardwareAccelerated()。因为当一个view附加到一个硬加速的window上,它仍可以使用非硬件速的Canvas进行绘制操作。比如当为了高速缓存而把一个view画到一个bitmap中。

附链接请看Demo实例:

https://github.com/zspxsx/PictureCarouselAndNavigationTwo.git