1

This is my kotlin code:

class WebAppInterface(private val mContext: Context, private val myWebView: WebView) {
    @JavascriptInterface
    fun goToHello() {
        val myWebView = myWebView
        myWebView.loadUrl("file:///android_asset/hello.html")
    }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val myWebView: WebView = findViewById(R.id.webview)
        myWebView.settings.javaScriptEnabled = true
        myWebView.addJavascriptInterface(WebAppInterface(this, myWebView), "Android")
        myWebView.loadUrl("file:///android_asset/index.html")
    }
}

But it's crash.

Caused by: java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread.

How can I fix this? I found a solution by searching but this was java code. Kotlin and Java are compatible but did not run due to a syntax error. (I think it's because I don't know Kotlin and Java. Anyway)

I'm a JavaScript-based full stack developer and I don't have any Android knowledge so I only wanted to use webviews. But this is also very difficult for me. (It's like the period of chaos when I first learned JavaScript.)

Please tell me the solution. ps. If you have a good list of Kotlin's inheritance and scope concepts, please link.

msm082919
  • 617
  • 8
  • 24
  • Please try to comment `myWebView.loadUrl("file:///android_asset/hello.html")`from 'fun goToHello(...)' and print some log here and check if it crash or not. – Hello World Mar 03 '20 at 04:54

3 Answers3

9

You should use Runnable and Post to WebView Handler.

myWebView.post(Runnable {
   myWebView.loadUrl("file:///android_asset/index.html")
})
Roman
  • 2,464
  • 2
  • 17
  • 21
2

Try This

mWebView.post(object:Runnable { 
public override fun run() { 
   mWebView.loadUrl("") 
   } 
}) 
Muhammad Mubeen
  • 153
  • 1
  • 8
1

As the link you posted here the problem is because

the JavaScript method is executed on a background (i.e. non-UI) thread. You need to call all Android View related methods on the UI thread. You can achieve what you need with:

The kotlin solution is the following

    val myWebView: WebView = findViewById(R.id.webview)
    //Apply webview's properties if it's not null
    myWebView?.run {
        settings.javaScriptEnabled = true
        addJavascriptInterface(WebAppInterface(this, myWebView), "Android")
        post {
            loadUrl("file:///android_asset/index.html")
        }
    }

As you can see here there a particular instruction here run this instruction is a part of the kotlin's scope functions.

Probably this tutorial that is designed for javascript developers might be helpul to kick start with kotlin https://dev.to/cassiozen/kotlin-for-js-devs-part-1-5bld