有没有一种方法来禁用Android 4.0.3的硬件加速?

我最近偶然发现了一个与Android 4.0.3的问题,在应用程序启动(即在其他Android版本工作正常),即时获取下面的exception:

java.lang.NullPointerException at android.view.GLES20RecordingCanvas.drawPatch(GLES20RecordingCanvas.java:97) at android.graphics.NinePatch.draw(NinePatch.java:125) at android.graphics.drawable.NinePatchDrawable.draw(NinePatchDrawable.java:189) at android.widget.ImageView.onDraw(ImageView.java:892) at android.view.View.draw(View.java:10978) at android.view.ViewGroup.drawChild(ViewGroup.java:2887) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489) at android.view.ViewGroup.drawChild(ViewGroup.java:2885) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489) at android.view.View.getDisplayList(View.java:10415) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597) at android.view.View.getDisplayList(View.java:10380) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597) at android.view.View.getDisplayList(View.java:10380) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597) at android.view.View.getDisplayList(View.java:10380) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2597) at android.view.View.getDisplayList(View.java:10380) at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:842) at android.view.ViewRootImpl.draw(ViewRootImpl.java:1910) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1634) at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4424) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(Native Method) 

这与启用硬件加速相关,只要我在清单上禁用它,应用程序开始工作就好了。

通过search,我在Romain Guy的一些对话中发现了一个日志 (在doc中search“drawPatch”),在那里他讨论了一些可能导致这个问题的原因,尽pipe没有提出解决方法或修复方法,不知道是否我应该禁用硬件加速只为这个版本的android,或者如果有一个解决方法吗?

谢谢你的时间。

Solutions Collecting From Web of "有没有一种方法来禁用Android 4.0.3的硬件加速?"

所以AC在他的评论中提到了这一点,但让我详细说明一下。

您可以在值文件中创build一个布尔值,并将其保存在正确的版本文件夹中。 在你的清单下

看看这个post: https : //plus.google.com/+AndroidDevelopers/posts/DcsFABkyuYM 。

看起来你想要定位值-v15 / bools.xml

http://developer.android.com/reference/android/os/Build.VERSION_CODES.html#ICE_CREAM_SANDWICH_MR1

您目前无法通过代码禁用窗口级别的硬件加速。

只有启用它。 我build议你在清单中默认禁用它:

 <application android:hardwareAccelerated="false"> <activity ... /> <activity android:hardwareAccelerated="false" /> </application> 

然后启用它到所有其他版本:

 if (Build.VERSION.SDK_INT != Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { getWindow().setFlags( WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); } 

您可以使用以下代码在运行时禁用单个视图的硬件加速:

 myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 

此信息在Android中可用- 控制硬件加速

我喜欢@sgarman链接的答案,因为它对代码影响很小,易于维护。 只是为了扩大这个链接,这是我做了什么,以禁用硬件加速只为Android v4.0.3,只为一个特定的活动,它为我工作(记得添加指定版本和编码的XML标题到各种bool.xml文件,因为维基编辑不会让我粘贴):

AndroidManifest.xml:标识托pipe违规视图的活动,并将其插入到该活动中:

 <activity android:hardwareAccelerated="@bool/isNotIceCreamSandwich" ... </activity> 

文件path:res / values / bool.xml:

 <resources> <bool name="isNotIceCreamSandwich">true</bool> </resources> 

文件path:res / values-v14 / bool.xml:

 <resources> <bool name="isNotIceCreamSandwich">false</bool> </resources> 

文件path:res / values-v16 / bool.xml:

 <resources> <bool name="isNotIceCreamSandwich">true</bool> </resources> 

这是一个有趣的错误,导致硬件加速工作(有时)。 过去几天我一直在寻找答案。 这是logging在ICS,但我已经注意到我的testing手机之一三星Galaxy S3运行4.1.2大多数人build议closures硬件加速。 我不想这样做导致硬件加速,使我的animation如此顺利。 所以我发现如果我重写draw()尝试和捕获空指针exception硬件加速function工作(大部分时间),足以让你永远不会注意到他们不工作或抛出exception。 在我的情况下,我正在做一个自定义的视图,并有一些自定义绘图。 简单的检查null不起作用(canvas == null),这就是为什么这个bug是一个痛苦。 所以我做了这个:

  @Override public void draw(Canvas canvas) { try{ super.draw(canvas); mCanvas=canvas; }catch(java.lang.NullPointerException e){ Log.e("mytag","MyCustomView::draw():"+e); } if(mCanvas==null) return; ... 

然后默默地尝试,并抓住任何NPE的个人绘画陈述。 我第一次看到这个bug,我试图抓住整个draw()代码。 这对大多数手机都有效,但在运行4.1.2的三星s3上却造成闪烁。 所以我使用了上面的方法,并沉默地尝试每次调用someObject.draw(mCanvas)catch时,解决了完全消除所有闪烁(硬件加速视图caching和新canvas之间的不一致)的问题。 希望这可以帮助! 比把HWA关掉更好!