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]。