2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Hardware acceleration によって Canvas が動かない場合の対処法

Posted at

AndroidのカスタムView内で使用していたCanvas#clipPath()UnsupportedOperationExceptionが発生したので調査していたところ、原因が「Hardware acceleration」という聞きなれない機能でした。
同じようにハマる人がいそうなので、「Hardware acceleration」の概要と制御の仕方をメモしておきます。
カスタムViewを作る人は知っておいたほうがいいです。

概要

ハードウェアアクセラレーションはViewの描画処理にGPUを使用することで効率化する機能です。

以下、注意点。

  • Hardware acceleration はAPIレベル14以上でデフォルトON
  • 標準のViewとDrawableを使う分には常にONで影響なし
  • 全ての描画処理をサポートしているわけではないので、ONになっているとカスタムViewで問題がでる場合がある
    • 意図しない描画になったり、最悪例外が発生してクラッシュします。今回はCanvas#clipPath()がAPIレベル18以上でないとサポートされていなかったので例外発生しました。
    • 各メソッドのサポート状況で自分が使っているメソッドをサポートしているAPIレベルを確認しておくことをオススメします

設定方法

以下のレベルでハードウェアアクセラレーションの制御が可能です。
(具体的な制御方法は最後の参考リンクの公式ドキュメントを参照してください)

  • Application => AndroidManifest.xmlで設定
  • Activity => AndroidManifest.xmlで設定
  • Window => コードで設定
  • View => コードで設定、ただし現在OFFにすることだけ可能

使いたいメソッドをサポートしているAPIレベルを確認して、満たしていないときはOFFにする、という対応が一番簡単だと思います。
今回は、以下のようにカスタムViewの例のように、サポートしていないAPIレベルの場合は、ビューレベルでOFFにすると意図した描画になりました。

    @Override
    protected void onDraw(Canvas canvas) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) {
            // Turn off hardware acceleration to use Canvas#clipPath()
            // See https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
            setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        }
        canvas.clipPath(mPath);
        super.onDraw(canvas);
    }

参考

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?