Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UnsupportedOperationException in GLES20Canvas.clipPath with hardware acceleration disabled on view

I have hardware acceleration enabled in my app but I have disabled it for one of my views because I had problems with stroke caps and other things.

Now I'm getting this stack trace in the Google Play Crash Errors console:

java.lang.UnsupportedOperationException
at android.view.GLES20Canvas.clipPath(GLES20Canvas.java:287)
at com.myapp.MyCustomView.onDraw(SourceFile:288)
at android.view.View.draw(View.java:9310)
at android.view.View.getDisplayList(View.java:8773)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:2298)
...
at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:609)
at android.view.ViewRoot.draw(ViewRoot.java:1634)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1450)
at android.view.ViewRoot.handleMessage(ViewRoot.java:2094)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:132)
at android.app.ActivityThread.main(ActivityThread.java:4123)
...

I have specified android:hardwareAccelerated="true" in AndroidManifest.xml. But I specifically disabled hardware acceleration in the constructor of my custom view:

    public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);

            // ... code omitted

            // disable acceleration because Paint.setStrokeCap(Cap.ROUND) is not working otherwise
            Compatibility.disableHardwareAcceleration(this);
    }

With compatibility being this:

public class Compatibility {
        // View.setLayerType() was introduced in Honeycomb
        private static Method setLayerTypeMethod = getMethod(View.class, "setLayerType", int.class,
                        Paint.class);

        private static Method getMethod(Class<?> clazz, String name, Class<?>... parameterTypes) {
                try {
                        return clazz.getMethod(name, parameterTypes);
                }
                catch (NoSuchMethodException e) {
                        return null;
                }
        }

        private Compatibility() {
        }

        public static void disableHardwareAcceleration(View view) {
                try {
                        if (setLayerTypeMethod != null) {
                                int layerType = 1; // View.LAYER_TYPE_SOFTWARE
                                setLayerTypeMethod.invoke(view, layerType, null);
                        }
                }
                catch (Exception ignored) {
                }
        }
}

Unfortunately the Crash Errors console does not reveal information about the Android OS version or device.

Any ideas what might be going on?

like image 878
devconsole Avatar asked Apr 16 '12 12:04

devconsole


1 Answers

There is a know issue where a view is still drawn using hardware acceleration even if LAYER_TYPE_SOFTWARE was set. Details are here

As a workaround you can do two things

  1. use Canvas.isHardwareAccelerated() to skip the problematic code.
  2. draw the problematic stuff into a bitmap and and draw this with canvas.drawBitmap() onto the hardware accelerated view.
like image 70
Renard Avatar answered Nov 19 '22 20:11

Renard