canvas.clipPath() 在少数设备上不起作用

Posted

技术标签:

【中文标题】canvas.clipPath() 在少数设备上不起作用【英文标题】:canvas.clipPath() not working in few devices 【发布时间】:2014-05-07 06:37:03 【问题描述】:

我在少数设备中遇到了 canvas.clipPath() 的问题。它在模拟器和一些高端设备(如 MotoG 和 nexus 平板电脑)中运行良好。但是当我在朋友的手机中测试时,我添加的 Square 视图没有被添加,并且应用程序崩溃并给出以下错误。

我尝试了这个问题的解决方案android UnsupportedOperationException at Canvas.clipPath,当我添加了该问题的答案中所说的 if 语句时,方形视图也没有添加到我的其他设备(MotoG 和 nexus)中。所以我不能在我的情况下使用那个解决方案。

但是,如果我只是注释掉 canvas.clipPath(); 就会在我朋友的手机中添加方形视图;但正如预期的那样,我的一些功能不起作用。 我该如何解决这个问题。请指教。在此先感谢:)

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)

我在我的方形视图类的这个函数中遇到错误我在我的 onDraw 方法中调用这个函数并传递它的画布。

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);

【问题讨论】:

@GrIsHu 我添加了导致错误的函数,canvas.clipPath 在该函数中给出错误 【参考方案1】:

Android 具有糟糕的(缺少硬件)后备功能。您的确切情况在已选中“使用主机 GPU”的模拟器中不起作用(至少在我的 4.2.2 中是这样)。所以实际的硬件会以两种方式做出反应(我已经看到了):

    抛出异常(例如您的情况) 尽量做到最好(在我的例子中,路径边界矩形被计算并应用为剪切矩形而不是路径)

就我所见,软件渲染将解决该问题(但可能会更慢)。

【讨论】:

我猜你是对的。我现在已将 canvas.clipPath 包含在 try-catch 中。所以现在它在支持它的设备中工作,在不支持没有clipPath的设备中工作(更多imp而不会崩溃)。但我需要找到一个解决方案,以便它尽快在所有设备上运行。 嘿,我尝试将其渲染为位图,然后在 onDraw() 中调用 canvas.drawBimap 并传递我渲染的位图。它似乎有效,但由于我正在更新我的正方形,它的高度和宽度等它留下了之前绘图的痕迹。我也试过了 canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);但仍然可以看到之前的绘图“轮廓”我也尝试将 reset() 调用到我正在使用但它不起作用的路径 clipPath 在 4.0.3 模拟器中失败,但在 4.3 和 4.4.2 中成功。这三个都打开了“使用主机 GPU”选项。

以上是关于canvas.clipPath() 在少数设备上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Android Canvas ClipPath锯齿问题

Android画圆形图片,clippath方式/Xfermode方式

Android clipPath导致卡顿

iOS 小部件在少数 iPhone5S 上不起作用

相机预览在少数 Android 设备上延伸

应用程序在少数模拟器上运行,但在真实设备上崩溃 [重复]