androidでのUIとHandlerについて

2011年1月10日

SurfaceViewなどで、スレッドを作って、処理ついでにUIの項目(TextViewなど)を更新しようとしたときに、普通にやると

CalledFromWrongThreadException

というエラーが出てしまう。

AndroidアプリのUIはシングル・スレッド モデルで、スレッドからUIを操作しようとすると例外が発生してしまうのです。

悪い例

while (thread != null) {
  Canvas canv = holder.lockCanvas();

  /*
   * TextViewに「roop」をセットする
   * ※ここで例外が発生する
   */
  showTime.setText("roop");

  canv.drawColor(Color.BLUE);
  Paint a = new Paint();
  a.setColor(Color.BLACK);
  a.setTextSize(20);
  canv.drawText("test", 10, 20, a);

  holder.unlockCanvasAndPost(canv);
  try {
    Thread.sleep(100);
    Thread.yield();
  } catch (Exception e) {
  }
}

この問題を回避する方法としてHandlerを使用して、UIにアクセスする方法があります。

Handlerインスタンスを生成し、postメソッドで実行する処理を与えてやることで

UIスレッドでHandlerに蓄積された処理を実行することが出来ます。

while (thread != null) {
  Canvas canv = holder.lockCanvas();

  //
  mHandler.post(new Runnable() {
    @Override
    public void run() {
      showTime.setText("roop");
    }
  });

  canv.drawColor(Color.BLUE);
  Paint a = new Paint();
  a.setColor(Color.BLACK);
  a.setTextSize(20);
  canv.drawText("test", 10, 20, a);

  holder.unlockCanvasAndPost(canv);
  try {
    Thread.sleep(100);
    Thread.yield();
  } catch (Exception e) {
  }
}

アンケート