2

キャンバスアニメーション中に子ビューをクリップするためにdrawChildをオーバーライドするカスタムAdapterViewがあります。

これはハニカムではうまく機能するようですが、Android4.0タブレットにロードされると激しい死を迎えます。これは、Android 4.0がデフォルトでハードウェアアクセラレーションをオンにしており、使用している1つ以上のキャンバスメソッドが、使用している特定のデバイス(ICS4.0.3を搭載したAcerA100)でハードウェアアクセラレーションをサポートしていないためだと思います。

これが私のdrawChildメソッドです(私のNinjaMenu.javaクラスから):

@Override
    protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
        final int top = child.getTop();
        final int left = child.getLeft();
        Bitmap bitmap = child.getDrawingCache();
        if (bitmap == null) {
            child.setDrawingCacheEnabled(true);
            child.buildDrawingCache();
            bitmap = child.getDrawingCache();
        }
        if (mCutPath != null) {
            // clip child views so that they partially show
            // as menu is expanded
            canvas.clipPath(mCutPath);
            canvas.drawBitmap(bitmap, left, top, null);
        }

        return false;
    }

mCutPathは、コードの他の場所で作成されたPathオブジェクトです(この問題には重要ではありません)。

AdapterViewが子を描画しようとするとすぐに発生する例外は次のとおりです。

FATAL EXCEPTION: main
java.lang.UnsupportedOperationException
    at android.view.GLES20Canvas.clipPath(GLES20Canvas.java:408)
    at com.phunware.funimation.android.views.NinjaMenu.drawChild(NinjaMenu.java:529)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    at android.view.View.draw(View.java:10986)
    at android.view.View.getDisplayList(View.java:10422)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2850)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    at android.view.View.getDisplayList(View.java:10420)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2850)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    at android.view.View.draw(View.java:10986)
    at android.widget.FrameLayout.draw(FrameLayout.java:450)
    at android.view.View.getDisplayList(View.java:10422)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2850)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    at android.view.View.getDisplayList(View.java:10420)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2850)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    at android.view.View.getDisplayList(View.java:10420)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2850)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    at android.view.View.getDisplayList(View.java:10420)
    at android.view.ViewGroup.drawChild(ViewGroup.java:2850)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
    at android.view.View.draw(View.java:10986)
    at android.widget.FrameLayout.draw(FrameLayout.java:450)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2152)
    at android.view.View.getDisplayList(View.java:10422)
    at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:852)
    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)

ハードウェアアクセラレーションを完全に無効にする以外に、特定のキャンバス機能がハードウェアアクセラレーションをサポートしているかどうか、およびそれがオフになっていないかどうかを確認する方法はありますか?

4

1 に答える 1

3

悪いニュース:いいえ、特定の関数がハードウェアアクセラレーションをサポートしているかどうかをプログラムでチェックする方法はありません。

良いニュース:あなたはこれに遭遇した最初の人ではありません、そして問題のある機能(そしてハードウェアアクセラレーションに関する他の多くの良いビット)はここにうまく文書化されています:

  • キャンバス
    • clipPath
    • clipRegion
    • 絵を描く
    • drawPoints
    • drawPosText
    • drawTextOnPath
    • drawVertices
  • ペイント
    • setLinearText
    • setMaskFilter
    • setRasterizer

このドキュメントには、動作が異なるいくつかの関数もリストされていることに注意してください。

確実な回避策は、コード内の問題のある操作を特定し、代わりにそれらをビットマップに描画してから、ビットマップを高速化されたキャンバスにブリットすることです。

于 2012-05-02T19:03:10.743 に答える