TIL: Webview @JavascriptInterface methods run in a different thread

I was trying to update a LiveData in a ViewModel from a Javascript method within the Webview. The Kotlin method was being called but the LiveData was not being updated. There were no errors either.

This fails silently:

@JavascriptInterface
fun onSelection(selection: String) {
    readerViewModel.setSelectedText(text)
}

After a lot of frustrating tinkering, I got the LiveData to update when I wrapped the update statement within a CoroutineScope.launch  on the Main thread.

This works:

@JavascriptInterface
fun onSelection(selection: String) {
    setSelectedText(selection)
}
...
private fun setSelectedText(text: String) {
    CoroutineScope(Dispatchers.Main).launch {
        readerViewModel.setSelectedText(text)
    }
}

It appears that the @JavascriptInterface methods are executed on a separate non-Main thread. Usually an exception is thrown when a ViewModel is updated from a non-Main thread in Kotlin. Surprisingly (and very confusingly), this exception isn’t thrown when updating the ViewModel from @JavascriptInterface. It just fails silently :/