「Only the original thread that created a view hierarchy can touch its views」の対処方法 | Androidアプリ開発

※当サイトはアフィリエイト広告を利用しています。

Androidアプリ開発において、「Only the original thread that created a view hierarchy can touch its views」の対処方法を紹介します。
スポンサーリンク


発生するサンプルコード

例えば以下のようなサンプルコードでボタンを押すと、「Only the original thread that created a view hierarchy can touch its views」のエラーで出てアプリがクラッシュします。

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/BT"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Change message"
        />

    <TextView
        android:id="@+id/TV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        />

</LinearLayout>

MainActivity.java
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.BT).setOnClickListener(view -> {
            Thread thread = new Thread(() -> {
                TextView tv = findViewById(R.id.TV);
                tv.setText("New message!!");
            });
            thread.start();
        });

    }
}

原因

原因はUIとは別のスレッドからUI要素を変更しているためです。

具体的に言えば、上記のサンプルコードのjavaファイルの9行目です。

対処方法

なので対処方法としてはUIスレッドからUI要素を変更してやればOKです。UIスレッドからコードを実行するにはrunOnUiThreadというメソッドを使用します。

以下、サンプルコードです。こうすればクラッシュしなくなります。

MainActivity.java
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.BT).setOnClickListener(view -> {
            Thread thread = new Thread(() -> {
                TextView tv = findViewById(R.id.TV);
                runOnUiThread(() -> tv.setText("New message!!") );
            });
            thread.start();
        });

    }
}

まとめ

Androidアプリ開発において、「Only the original thread that created a view hierarchy can touch its views」の対処方法を紹介しました。