Android Javaに触れて1年になる。すでに地図アプリGISは実用に供している。 地図アプリGISの後継として、地図アプリMapの開発を進めている。 プログラムのスリム化とパフォーマンスの向上を目指している。 急ぐ必要はないので、原点からゆっくりと進めている。
アプリGISでもときどき経験しているが、アプリMapではメニューやボタンが反応しなくなることが多くなった。
また、レンダリングスレッドで invalidate() を発行したとき、 メインスレッドの onDraw() が動くまでに 20ms ほどかかることが分かった。少々大きすぎる。
かかるとき、原点に返り、小さなアプリを作成して、やはり、 同じように時間がかかったり、メニューやボタンが反応しなくなることがあるかを確認したい。
タイトルは描画入門としたが、まずは、invalidate() から onDraw() の実行開始までの時間を調べたい。
テストアプリは記事[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; } } }
地図アプリではこれまで、invalidate() を発行して、onDraw() を呼び出してきた。 最近、invalidate() が無視されるような現象が起きるようになった。 原因は、別にあるかも知れないが、ひとまず、invalidate() の代わりに handler を使ってみる[3],[4]。