【Android】「Only the original thread that created a view hierarchy can touch its views.」の対処法

今日の記事は、Androidアプリ開発中に遭遇したエラーについてです。
修正はそこまで大変ではなかったのですが、使用頻度が低く、忘れそうだったので備忘録としてまとめます。

エラーは「Only the original thread that created a view hierarchy can touch its views.」というもので、こちらはメインスレッド以外で、TextView などの UI を変更しようとすると発生するエラーです。
シンタックスエラーとは違い、ビルドは通ってしまうので要注意ですね。

 

では、早速対処法についてご紹介。
今回参考にさせていただいたサイトはこちらです。

メインスレッド以外でUIを変更する方法 – Accele Biz IT開発技術 調査報告書
http://accelebiz.hatenablog.com/entry/2016/09/01/061934

エラーが発生したコードはこちら。

TextView textView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    textView = findViewById(R.id.[ID名]);
    showMessage();
}

private void showMessage(){
    try {
        /* 処理 */
        textView.setText("[表示したい文字列]");
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

一部改変していますが、だいたいこんな感じ。
で、問題は、showMessage() 内の try/catch で指定した、setText() です。
やった事がなかったので知らなかったのですが、このようにメインスレッド以外で UI を操作することはできないようでした。

ですが、対処法もちゃんと用意されていました。
参考サイトそのままですが、Handler を使用して、別スレッドからメインスレッドに処理を依頼する方法です。
具体的には下記のとおりです。

private void showMessage(){
    final Handler mainHandler = new Handler(Looper.getMainLooper());
    try {
        /* 処理 */
        mainHandler.post(() -> {
            textView.setText("[表示したい文字列]");
        });
    } catch (JSONException e) {
        e.printStackTrace();
    }
}

2行目に Handler を宣言し、TextView の操作の記述を mainHandler.post() で囲うだけです。
これを追加したところ、問題なく TextView の操作を行うことができました。

 

以上、TextView などの UI の操作をメインスレッド以外から行う方法でした。
今回の解決策は、例えば何らかの処理を別スレッド&非同期で行っていて、結果が返ってきたタイミングで UI を変更したい、等の場合にも使えるかと思います。
もし、同じエラーでお困りの場合は、是非参考にしていただければと思います。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG