0

I am facing problem with canvas.clipPath() in few devices. Its working fine in emulator and some high end devices like MotoG and nexus tablet. But when I tested in my friends cell phone the Square view which I am adding is not added and the application crashes giving the below error.

I tried the soln of this question Android UnsupportedOperationException at Canvas.clipPath when I add the if statement as said in the ans of that question the square view is not added in my other devices as well (MotoG and nexus). So I cant use that soln in my case.

However the square view is added in my friends cell phone if I just comment out canvas.clipPath(); but as expected few of my features are not working. How shall I solve this problem. Please advice. Thanks in advance :)

05-07 11:45:54.656: E/AndroidRuntime(5997): FATAL EXCEPTION: main
05-07 11:45:54.656: E/AndroidRuntime(5997): java.lang.UnsupportedOperationException
05-07 11:45:54.656: E/AndroidRuntime(5997): at  android.view.GLES20Canvas.clipPath(GLES20Canvas.java:429)
05-07 11:45:54.656: E/AndroidRuntime(5997): at example.Square.addText(Square.java:260)
05-07 11:45:54.656: E/AndroidRuntime(5997): at example.Square.onDraw(Square.java:140)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.View.draw(View.java:11054)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.View.getDisplayList(View.java:10493)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewGroup.drawChild(ViewGroup.java:2958)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2596)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.View.draw(View.java:11057)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.View.getDisplayList(View.java:10493)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewGroup.drawChild(ViewGroup.java:2958)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2596)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.View.draw(View.java:11057)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.View.getDisplayList(View.java:10493)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewGroup.drawChild(ViewGroup.java:2958)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2596)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.View.getDisplayList(View.java:10491)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewGroup.drawChild(ViewGroup.java:2958)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2596)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.View.getDisplayList(View.java:10491)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewGroup.drawChild(ViewGroup.java:2958)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2596)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.View.draw(View.java:11057)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.widget.FrameLayout.draw(FrameLayout.java:463)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2145)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.View.getDisplayList(View.java:10493)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:880)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewRootImpl.draw(ViewRootImpl.java:1911)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1635)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2455)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.os.Looper.loop(Looper.java:137)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at android.app.ActivityThread.main(ActivityThread.java:4424)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at java.lang.reflect.Method.invokeNative(Native Method)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at java.lang.reflect.Method.invoke(Method.java:511)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:817)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:584)
05-07 11:45:54.656: E/AndroidRuntime(5997):     at dalvik.system.NativeStart.main(Native Method)

I am getting error in this function of my square view class I am calling this function inside my onDraw method passing its canvas.

private void addText(Canvas canvas){
    //setLayerType(View.LAYER_TYPE_SOFTWARE, null);
    //Setting text

    canvas.clipPath(path);

    bitmapWidth = right+x+ mWidth;
    bitmapHeight = bottom+y+mHeight;

    if(bitmapWidth <= 10){
        bitmapWidth = 10;
    }
    if(bitmapHeight <= 10){
        bitmapHeight = 10;
    }

    bitMap1 = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);

    Canvas canvas1 = new Canvas(bitMap1);

    tp.setColor(textColor);
    txtWidth = (right+x+ mWidth)-(left+x);
    txtHeight = (bottom+y+mHeight)-(top+y);

    if(left+x < 0 ){
        txtWidth = (right+x+ mWidth);
    }
    if(top+y < 0){
        txtHeight = (bottom+y+mHeight);
    }
    pdl = new PlacableDynamicLayout(string,tp,txtWidth, txtHeight,Alignment.ALIGN_CENTER,1.0f,1.0f,false,Anchor.ANCHOR_TOP,1);
    pdl.draw(canvas1);

    canvas.drawBitmap(bitMap1, (left+x), (top+y) , paint);
}
Community
  • 1
  • 1
ik024
  • 3,566
  • 7
  • 38
  • 61
  • @GrIsHu i have added the function which was giving error the canvas.clipPath was giving error inside that function – ik024 May 07 '14 at 07:22

1 Answers1

4

Android has miserable (missing HW) fallback functionality. Your exact situation will not work in emulator which has "Use host GPU" checked (at least in my 4.2.2. it is so). So the actual hardware will react in two ways (that I have seen):

  1. throw an Exception (such as in your case)
  2. Try to do the best it can (in my case Path bounding rect is calculated and applied as clipping rect instead of the Path)

Software rendering will fix the issue as far as I have seen (but will probably be slower).

velis
  • 8,747
  • 4
  • 44
  • 64
  • i guess u r right. I have included the canvas.clipPath inside a try-catch for now. So now its working in devices which supports it n the devices which doesnt support works without clipPath (more imp without crashing). But i need to find a soln so that it works in all devices soon. – ik024 May 08 '14 at 04:49
  • Hey i tried to render it to a bitmap and then calling canvas.drawBimap in onDraw() and passing my rendered bitmap. It seems to work but since I am updating my square its height and width etc etc its leaving trail of previous drawing. I tried this as well canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); but still the previous drawing "outline" is visible I also tried calling reset() to path which I am using but its not working – ik024 May 09 '14 at 05:07
  • clipPath fails in 4.0.3 emulator, but succeeds in 4.3 and 4.4.2. All three have "Use Host GPU" option turned on. – WindRider Sep 20 '14 at 12:16