UIを操作するのにhandlerを使う理由 thread WebViewCoreThread exiting due to uncaught exception

Androidではメインのスレッド以外はUI(画面表示機能)にアクセスすることができない。
このためほかのスレッドなどでUIにアクセスすると次のような例外が発生します。

[参考記事] Androidでマルチスレッド処理をする方法

W/dalvikvm(  646): threadid=17: thread exiting with uncaught exception (group=0x4001aa28)
E/AndroidRuntime(  646): Uncaught handler: thread WebViewCoreThread exiting due to uncaught exception
E/AndroidRuntime(  646): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
E/AndroidRuntime(  646):        at android.view.ViewRoot.checkThread(ViewRoot.java:2629)
E/AndroidRuntime(  646):        at android.view.ViewRoot.invalidateChild(ViewRoot.java:558)
E/AndroidRuntime(  646):        at android.view.ViewRoot.invalidateChildInParent(ViewRoot.java:584)
E/AndroidRuntime(  646):        at android.view.ViewGroup.invalidateChild(ViewGroup.java:2391)
E/AndroidRuntime(  646):        at android.view.View.invalidate(View.java:4742)

これをソースコードでみると

[参考記事] Androidのソースファイルを入手する方法

/frameworks/base/core/java/android/view/ViewRoot.java

public final class ViewRoot extends Handler implements ViewParent,
  View.AttachInfo.Callbacks {
………
…
………
  void checkThread() {
    if (mThread != Thread.currentThread()) {
      throw new CalledFromWrongThreadException(
        "Only the original thread that created a view hierarchy can touch its views.");
    }
  }
………
…
………
}



checkThredメソッドで、処理を行うThread.currentThread()がメインのスレッドmThreadかどうかを判定しています。

メインスレッド以外からUIを操作するには、handlerを使って、タスクをRunnableとしてUIスレッドに投げます(post)。



そうするとMessage QueueにRunnableがたまり、順々に処理されます。

Handler handler= new Handler();

handler.post(new Runnable() {
  @Override
  public void run() {
    textView.setText("Hello!");
  }
});

マルチスレッド処理を行うときには、これを意識して実装します。
またAndroidではUI処理を行うために独自にAsyncTaskというマルチタスクを行うオブジェクトがあり、handlerを使用しない方法もあります。

[参考記事] Androidでマルチスレッド処理をする方法
[参考記事] Androidのソースファイルを入手する方法

関連記事

スポンサーリンク

閲覧領域からはみ出す要素がない状態でもスクロールバーが表示されることがある

ホームページ製作・web系アプリ系の製作案件募集中です。

上に戻る