[Android] Handlerを使って別スレッドからUIを変更する

Android開発してる人なら基礎中の基礎なんでしょうが、ハマってしまったのでその時のメモ。

タイトルの通り、別のスレッド処理を立ててそちらの結果を使って画面のUIを変更したいというお話。

CalledFromWrongThreadExceptionエラー

Androidのアプリは、メインスレッド以外のスレッドでUIを変更しようとすると、下記のような例外が発生します。

android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Androidアプリはシングルスレッドで使用することが前提のようで、マルチスレッドで動かす場合、メインのスレッドでしかUIの変更はできないようになっている模様です。

とはいえ、重い処理を別のスレッドを作って動かして、結果をメインの画面に反映させたいなんてことはよくありますよね。今回、私も別スレッドが終了したことを画面に反映させたかったのですが、上記のエラーが発生して、さてどうしたものかと思っていました。

Handlerをつかう

上記のエラーをgoogleで検索すると、Handlerを使うと解決するというのがすぐ見つかりました。基本なのでしょう(汗)。

まず、メインのスレッドでHandlerクラスを作成します。onCreateにでも書いておきます。

@Override
protected void onCreate(Bundle savedInstanceState) {
        ︙
    Handler handler = new Handler();
        ︙
}

スレッド内でhandlerを呼び出して画面のUIを変更します。

new Thread(new Runnable() {
    @Override
    public void run() {
            ︙
        handler.post(new Runnable() {
            @Override
            public void run() {
                textView.setText("Thread Finished.");
            }
        });
    }
}).start();

これで解決です。

参考