【Android】”WebView method was called on thread ‘JavaBridge'” の解決策

Android Studioでアプリ開発中・・・

こんなエラーに遭遇しました。

初めて遭遇するよくわからないエラーです。

このエラーの解決策についてまとめます。

問題は@JavascriptInterfaceの関数内で起きた

開発には主にWebViewを使ってます。

そこでこういうコードを書いてました。

  • JS側からJavaメソッド呼び出したい
  • MainActivityにそのメソッドを作成
  • @JavascriptInterfaceをつける

要するにWebView側のJavaScriptからMainActivityのメソッドを呼び出したかったわけです。呼び出し方はActivity側のメソッドに @JavascriptInterface  をつけるだけです。

 

具体的にはこういうコードですね。

▼ 実際のコード(のイメージ)

これを実行したところ冒頭のエラーに

どうやら @JavascriptInterface  がついたメソッドはメインスレッドとは別で実行されるらしく、その中でWebView側のメソッドを呼び出すと「スレッドが違うじゃん!」という事情でエラーが出るみたいです。

解決策はrunOnUiThreadで実行するだけだった

この問題の解決策は簡単。

単にUIスレッド内で実行すればいいだけです。

そのために runOnUiThread が用意されてます。

▼ 公式での説明

Runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.

引用元 : https://developer.android.com/reference/android/app/Activity#runOnUiThread(java.lang.Runnable)

▼ この説明の簡単な意訳

UIスレッドの中で特定のアクションを実行します。もし現在のスレッドがUIスレッドならアクションは即時に実行されます。もし現在スレッドがUIスレッドじゃないなら、そのアクションはUIスレッドのイベントキューに登録して後で実行されます。

こういうメソッドがありました。

単純にこれ使えばいいだけですね。

 

実際に試したコートがこういうのです。

▼ こういうコードに変更

このように runOnUiThread(new Runnable(){...})  のようにWebView側の処理をUIスレッドに移すだけです。このテクニックは通信処理とかでもよく使うことが多いかもしれません。

実際にこのコードを試したらJSコード実行もうまくいきました。これで Activity ⇔ WebView の間で相互通信できるようになります。

UIスレッド外からWebView操作は気を付けよう

簡単にまとめるとこうなります。

  • @JavascriptInterfaceは別スレッド実行
  • だからUI操作的なコードはエラーになる
  • 単純にrunOnUiThreadから呼び出せばOK

この点はWebViewに限らず気を付けたいですね。

UIスレッドなのか、そうでないのか・・・

それをコードを書くときに意識するのが大事です。

間違いなどはコメント欄から。ではまた (@^^)/~~~