トップAndroid Java > 描画入門

Android Java: 描画入門

はじめに

Android Javaに触れて1年になる。すでに地図アプリGISは実用に供している。 地図アプリGISの後継として、地図アプリMapの開発を進めている。 プログラムのスリム化とパフォーマンスの向上を目指している。 急ぐ必要はないので、原点からゆっくりと進めている。

アプリGISでもときどき経験しているが、アプリMapではメニューやボタンが反応しなくなることが多くなった。

また、レンダリングスレッドで invalidate() を発行したとき、 メインスレッドの onDraw() が動くまでに 20ms ほどかかることが分かった。少々大きすぎる。

かかるとき、原点に返り、小さなアプリを作成して、やはり、 同じように時間がかかったり、メニューやボタンが反応しなくなることがあるかを確認したい。

タイトルは描画入門としたが、まずは、invalidate() から onDraw() の実行開始までの時間を調べたい。

onDraw の反応時間[2023.1.8]

テストアプリは記事[1]を参考にする。 まずは、ボタンを押してから onDraw() の実行が始まるまでの時間を計測する。

次のような簡単なケースの場合、invalidate()発行から onDraw()開始までの経過時間は 1 ms か 2 ms であることを確認できた。地図アプリMapでの 約20ms は余りにも大きすぎる。 しかし、直前のCPU負荷が高かった場合、待ち時間が長くなってしまうようである。

    
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        MyView myView = new MyView(this);
        setContentView(myView);
    }

    static class MyView extends View {
        Paint paint;
        long start;

        public MyView(Context context) {
            super(context);
            paint = new Paint();
        }

        @Override
        protected void onDraw(Canvas canvas) {
            System.out.printf("elapsed = %d ms\n", 
                    System.currentTimeMillis() - start);
            paint.setColor(Color.argb(255, 255, 0, 255));
            paint.setStrokeWidth(20);
            paint.setStyle(Paint.Style.STROKE);
            canvas.drawRect(300, 300,600, 600, paint);
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    break;
                default:
                    return true;
            }
            start = System.currentTimeMillis();
            invalidate();
            return true;
        }
    }

}

handlerを使う[2023.5.17]

地図アプリではこれまで、invalidate() を発行して、onDraw() を呼び出してきた。 最近、invalidate() が無視されるような現象が起きるようになった。 原因は、別にあるかも知れないが、ひとまず、invalidate() の代わりに handler を使ってみる[3],[4]。

A.リファレンス

[1] [Android] Canvas Paint で円や矩形を描画する
[2] [Android] ButtonをJavaコードだけで設定する
[3] UIを操作するのにhandlerを使う理由
[4] [Android] Canvas クリアーして再描画
[5] AndroidのViewでinvalidateが反映・更新、再描画されない件