序文
この例外は通常、非 UI スレッドで UI コンポーネントを更新しようとしたときに発生します。Android アプリケーションでは、UI コンポーネントは UI スレッド上でのみアクセスおよび更新できます。この例外は、非 UI スレッドから UI コンポーネントを更新しようとするとスローされます。
解決
この問題の解決策は、すべての UI 操作が UI スレッドで実行されるようにすることです。Android は、UI スレッドでコードを実行するためのいくつかのメカニズムを提供します。
1View.post(Runnable)
メソッドまたはView.postDelayed(Runnable, long)
メソッドを使用してコードを UI スレッドのメッセージ キューに置き、UI スレッドがそれを処理するのを待ちます。例えば:
view.post(new Runnable() {
@Override
public void run() {
// 在 UI 线程中执行操作
view.setText("Hello, world!");
}
});
2Activity.runOnUiThread(Runnable)
メソッドを使用して、アクティビティの UI スレッドでコードを実行します。例えば:
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
// 在 UI 线程中执行操作
view.setText("Hello, world!");
}
});
3Handler
またはなどのメカニズムを使用してAsyncTask
、コードを UI スレッドに入れて実行します。例えば:
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
// 在 UI 线程中执行操作
view.setText("Hello, world!");
}
});
// 或者使用 AsyncTask
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
// 在后台线程中执行操作
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// 在 UI 线程中执行操作
view.setText("Hello, world!");
}
}.execute();
上記のコードでは、操作はオブジェクトにパッケージ化されておりRunnable
、対応するメカニズムを使用してそれを UI スレッドに送信して実行します。これにより、非 UI スレッドでの UI コンポーネントの更新によって発生する例外が回避されます。
要約する
UI を変更するだけの場合は 2 番目のハンドラーを使用することをお勧めしますが、拡張性はそれほど高くなく、他のニーズがある場合は 3 番目のハンドラーの方がまだ非常に優れており、持ち運びが簡単です。