java.lang.IllegalStateException: Hardware acceleration can only be used with a single UI thread.
来源:互联网 发布:php超全局变量 编辑:程序博客网 时间:2024/05/18 00:25
今天在研究一个东西的时候有的真机上报这个错误 (我发现的是自己的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的加速)
Application <application android:hardwareAccelerated="true" ...>
2)activity(界面的加速)
<span style="font-size:14px;"><application android:hardwareAccelerated="true"> <activity ... /> <activity android:hardwareAccelerated="false" /></application></span>
3)Window 窗口
getWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
4)View级别
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
这里要注意的是:Window和View级别只能关闭硬件加速,而不能控制开启
判断一个view是否被硬件加速
有些时候,知道当前的View对象(尤其是那些定制的View对象)是否被硬件加速对应用程序来说是非常有用的。如果应用程序做了很多定制的绘图操作,并且不是所有的操作都会被新的渲染管道所支持,那么这种判断就特别有用。
有两种不同的方法来检查应用程序是否被硬件加速了:
View.isHardwareAccelerated():返回值为true,View对象跟一个被硬件加速的窗口绑定;反之,未加速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();
- java.lang.IllegalStateException: Hardware acceleration can only be used with a single UI thread.
- android编译错误之“Hardware acceleration can only be used with a single UI thread”,硬件加速
- Hardware acceleration can only be used with a single UI thread
- A TextureView or a subclass can only be used with hardware acceleration enabled.错误原因分析
- java.lang.IllegalStateException: ActionBarImpl can only be used with a compatible window decor layou
- java.lang.IllegalStateException: ActionBarImpl can only be used with a compatible window decor layou
- java.lang.IllegalStateException: ActionBarContextView can only be used with android:layout_width="
- java.lang.IllegalStateException: Realm access from incorrect thread. Realm objects can only be acce
- ActionBarImpl can only be used with a compatible window decor layout
- <merge /> can be used only with a valid ViewGroup root and attachToRoot=true
- android.view.InflateException: <merge /> can be used only with a valid ViewGroup root and attachToRo
- <merge /> can be used only with a valid ViewGroup root and attachToRoot=true
- @Field parameters can only be used with form encoding
- @Field parameters can only be used with form encoding
- you are calling a UIKit method that can only be invoked from the UI thread.
- Python SQLite3的问题sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in th
- java.lang.IllegalStateException: ScrollView can host only one direct child
- java.lang.IllegalStateException: ScrollView can host only one direct child
- 【codeforces】Grasshopper And the String(div2A)
- Android适配不同屏幕
- Qt:去掉Qt加载png图像文件时候的iccp警告
- 设计模式六大原则
- ASP.NET SignalR 高可用设计
- java.lang.IllegalStateException: Hardware acceleration can only be used with a single UI thread.
- RedHat 下如何安装g++编译器
- 【NOIP普及组】2016模拟考试(10.29)——摆花
- AlertDialog不显示message和title
- [NOIP2014][vijos1914]子矩阵(dp)
- 设计模式(Design Patterns)
- @GeneratedValue
- [java学习9]angularJS之指令练习
- GIT (分布式版本控制系统)