java.lang.IllegalStateException: Hardware acceleration can only be used with a single UI thread.

原创 2016年11月01日 15:04:23

今天在研究一个东西的时候有的真机上报这个错误 (我发现的是自己的coopal的4.4手机上),

这种情况是由于硬件加速的原因引起的

but 我在manifest中已经关闭了硬件加速,代码如下

 <application
        android:allowBackup="true"
        android:hardwareAccelerated="false"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >。。。。。。。。。。。

这个对大部分手机ok的         然而coopal的4.4手并没有多大作用,程序依旧惨死

后来上网搜了下,简单暴力的做法是

开发者模式中“强制使用GPU渲染”的选项开启了,关闭应该就不会开启硬件加速了。

既然都扯到硬件加速了,索性就来了解一下硬件加速吧  


从Android3.0(API Level 11)开始,Android 2D渲染管道能够更好的支持硬件加速。硬件加速执行的所有的绘图操作都是使用GPU在View对象的画布上来进行的。因为启用硬件加速会增加资源的需求,因此这样的应用会占用更多的内存。

硬件加速在target api大于等于14的情况下,是默认开启的,但是我们也可以显示的开启硬件加速。如果应用程序只使用标准的View和Drawable,那么打开全局硬件加速不会导致任何不良的绘制影响。然而,由于硬件加速并不支持所有的2D图形绘制操作,因此对于那些使用定制的View和绘制调用来说,打开全局硬件加速,会造成影响。对于这个问题,通常是对那些不可见的元素进行了异常或错误的像素渲染。为了避免这种问题,Android提供了多个级别的硬件加速操作(开启或者关闭),具体可见控制硬件加速。

这里⚠️ :如果应用程序执行了定制化的绘图,并且开启了硬件加速,那么就要在带有硬件加速的真机上测试,以便发现问题。 不支持的绘制操作描述了硬件加速的问题,以及如何解决它们。


四个级别的   硬件加速

1)application(app的加速)

在应用的Android清单文件中,把下列属性添加到元素中,能够开启整个应用程序的硬件加速:如下

Application  
<application android:hardwareAccelerated="true" ...>

2)activity(界面的加速)

如果应用程序不能正确的使用被打开的全局硬件加速,那么也可以在Activity级别上进行控制。在元素中使用android:hardwareAccelerated属性,能够启用或禁止Activity级别的硬件加速。以下示例启用全局的硬件加速,但却禁止了一个Activity的硬件加速:    同上面一样,在AndroidManifest中  
<span style="font-size:14px;"><application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application></span>

3)Window 窗口

如果需要更精细的控制,就可以使用下列代码来针对给定的Window来启用硬件加速
getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

4)View级别

在运行时,可以针对一个独立的View对象使用下列代码来禁止硬件加速:
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

这里要注意的是:Window和View级别只能关闭硬件加速,而不能控制开启

判断一个view是否被硬件加速

使用情况 :

有些时候,知道当前的View对象(尤其是那些定制的View对象)是否被硬件加速对应用程序来说是非常有用的。如果应用程序做了很多定制的绘图操作,并且不是所有的操作都会被新的渲染管道所支持,那么这种判断就特别有用。

有两种不同的方法来检查应用程序是否被硬件加速了:

View.isHardwareAccelerated():返回值为true,View对象跟一个被硬件加速的窗口绑定;反之,未加速
Canvas.isHardwareAccelerated():返回值为true,Canvas对象被硬件加速;反之,未加速
建议的话使用:因为View关联到一个硬件加速的window上,任然可以使用非硬件加速的canvas绘制。


View layers 

所有的Android版本View都可以在非屏幕内存(off-screen buffers)上渲染,使用view的drawing cache或者Canvas.saveLayer().非屏幕内存或者layers有许多用处,在对复杂对View做动画或者做一些叠加复合效果时可以得到更好的性能。 
在Android3.0之后可以使用View.setLayerType()来控制如何使用layers。

LAYER_TYPE_NONE: 默认行为,正常渲染,不会在off-screen buffer上备份

  LAYER_TYPE_HARDWARE :如果应用开启了硬件加速view渲染在硬件上,否则与LAYER_TYPE_SOFTWARE行为一样

LAYER_TYPE_SOFTWARE: 用软件渲染在一个bitmap上

使用硬件加速有更高的效率,如果产生兼容性问题,可以用setLayerType改变渲染方式。

View layers and animations

当应用程序被硬件加速的时候,硬件层能够传递更快、更平滑的动画。当播放具有复杂的绘图操作的动画时,以每秒60帧的速度播放不总是可能的。但是,可以通过使用硬件层把View对象渲染在硬件纹理中,缓解这种情况。硬件纹理能够被用于动画视图,这样在该View对象呈现动画时,就可以消除View对象所需要的重绘操作。除非该View对象的属性发生变化时(invalidate()方法被调用),它才会被重绘。如果在应用程序运行一个动画,并且没有获得想要的平滑结果,就要考虑在动画View上启用硬件层。

当一个View从硬件层被返回时,通过层方法处理的某些属性会被合成到屏幕上。因为它们不需要让View对象失效和重绘,所以设置这些属性是非常高效的。下面列出了影响层被合成的方式。调用这些属性设置器,会导致失效处理的优化,并且不会对目标View对象进行重绘:

alpha:改变层(layer)的透明度;x,y,translation,translation:改变层的位置;scaleX,scaleY:改变层的尺寸;rotation,rotation,rotationY:改变3D空间中层的方向;pivotX,pivotY:改变层的变换起源。

这些属性是在用ObjectAnimator对象给View对象设置动画时所使用的名称。如果想要访问这些属性,就要调用相应的set或get方法。例如,要修改alpha属性,就要调用setAlpha()方法。下面的代码展示了在3D空间中围绕Y轴旋转View对象的最有效的方法:

<span style="font-size:14px;">view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator.ofFloat(view, "rotationY", 180).start();</span>

View.setLayerType(View.LAYER_TYPE_HARDWARE, null);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "rotationY", 180);
animator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        view.setLayerType(View.LAYER_TYPE_NONE, null);
    }
});
animator.start();




参考:http://blog.csdn.net/xu_fu/article/details/48208795
http://www.2cto.com/kf/201405/299584.html

版权声明:本文为博主原创文章,未经博主允许不得转载。

Hardware acceleration can only be used with a single UI thread.

Hardware acceleration can only be used with a single UI thread.
  • huang15984
  • huang15984
  • 2016年11月17日 12:35
  • 448

android编译错误之“Hardware acceleration can only be used with a single UI thread”,硬件加速

今天在调试的时候碰到一个问题,在处理对话框点击完button使其消失的过程中,报错如下: java.lang.IllegalStateException: Hardware acceleration...
  • qq_22260247
  • qq_22260247
  • 2014年12月19日 16:44
  • 2406

Eclipse启动参数解决占用CPU占用过高

问题:一运行eclipse,CUP就飙到100%。 解决: 刚开始只调大最下面的-Xms512m,并不好用,运行的时候仍然死机。 后来查资料发现,不仅要调大最下面的数值,还要调大上面...
  • u010898441
  • u010898441
  • 2018年01月07日 21:44
  • 87

20行代码理解回调机制

20代码行理解回调机制 最近在学习android的过程中发现view的OnClickListener的回调机制很有趣,就学习回调的使用方法。 学习的内容分享给大家。...
  • yjg211314
  • yjg211314
  • 2015年08月30日 11:35
  • 915

一般报java.lang.NullPointerException的原因有以下几种

一般报java.lang.NullPointerException的原因有以下几种: ·字符串变量未初始化; ·接口类型的对象没有用具体的类初始化,比如: List lt; 会报错 L...
  • zwhfyy
  • zwhfyy
  • 2006年07月06日 16:56
  • 449536

Android开发中遇到Java.lang.NullPointerException解决办法

我们在开发软件的时候,不知道你是否遇到过Java.Lang.NullPointerException的错误,出现这和错误呢,不是大的错误,但是找不到的话,分分钟钟让你崩溃,所谓空指针的错误,就是你定义...
  • zhaomengszu
  • zhaomengszu
  • 2017年01月15日 15:01
  • 355

A TextureView or a subclass can only be used with hardware acceleration enabled.错误原因分析

A TextureView or a subclass can only be used with hardware acceleration enabled.
  • yjg211314
  • yjg211314
  • 2015年09月06日 10:27
  • 2137

android studio 1.0(135.1629389) 下载安装及问题解决

提供了android studio 1.0 谷歌最新版本的百度网盘下载地址和加载sdk组件信息超时的解决方案。...
  • yjg211314
  • yjg211314
  • 2014年12月10日 12:40
  • 2296

java.lang.nullpointerexceptiond的原因

重写doGet方法时,报错java.lang.nullpointerexception,每次都要重启tomcat测试,废了很大周折,才发现:编码字符集是GB2312,漏了GB,因为不存在2312这个对...
  • BaiJJMM
  • BaiJJMM
  • 2016年03月28日 20:05
  • 1150

java.lang.NullPointerException 空指针异常问题

1.所谓的指针,就是java中的对象的引用。比如String s;这个s就是指针。  2.所谓的空指针,就是指针的内容为空,比如上面的s,如果令它指向null,就是空指针。 3.所谓的空指针异常,...
  • qing101hua
  • qing101hua
  • 2015年05月03日 15:28
  • 56468
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java.lang.IllegalStateException: Hardware acceleration can only be used with a single UI thread.
举报原因:
原因补充:

(最多只允许输入30个字)