在 Kotlin 的 WebView 的 JavascriptInterface 中执行页面的 JavaScript

Executing a page's JavaScript inside a WebView's JavascriptInterface in Kotlin

作为一个例子,让我们假设一个项目,我有一个 WebView 实例,我正在我的主 activity 加载本地 HTML 文件:

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

        myWebView = findViewById(R.id.webview)
        myWebView.getSettings().setAllowContentAccess(true);
        myWebView.getSettings().setAllowFileAccess(true);
        myWebView.settings.javaScriptEnabled = true;
        myWebView.setWebChromeClient(WebChromeClient());
        myWebView.loadUrl("file:///android_asset/websrc/mainPage.html")
        myWebView.addJavascriptInterface(WebAppInterface(this), "Android")
    }    
}
class WebAppInterface(private val mContext: Context) {
    @JavascriptInterface fun getStatus() {
      MainActivity().myWebView.evaluateJavascript("setStatus('good to go!')", null)
      //Or: MainActivity().myWebView.loadURL("javascript:setStatus('good to go!')")
    }
}

我也有一个 JavascriptInterface,我想从那里调用 HTML 文件中的 Android.getStatus()

<html>
  <head>
    ...
  </head>
  <body>
    <div id="status"></div> 
  </body>
  <script>
    document.addEventListener('DOMContentLoaded', function() {
        Android.getStatus()
    })
    function setStatus(status) {
      document.querySelector('#status').innerHTML = status
    }
  </script>
</html>

到目前为止,我认为明白为什么这行不通。从我从 this or this, And especially in the documentation for WebView 之类的答案中了解到,我了解到 JavascriptInterface 和 WebView 在不同的线程上 运行,因此不会定义 setStatus() 之类的东西。到目前为止,我已经尝试使用 runOnUiThreadHandler()。查看 runOnUiThread 的示例:

@JavascriptInterface fun getStatus() {
      MainActivity().runOnUiThread(
                object : Runnable {
                    override fun run() {
                        MainActivity().myWebView.evaluateJavascript("setStatus('good to go!')", null)
                        //Or: MainActivity().myWebView.loadURL("javascript:setStatus('good to go!')")
                    }
                }
            )
    }

然而,这(以及 Handler 的使用)给了我:E/AndroidRuntime: FATAL EXCEPTION: JavaBridgelateinit property myWebView has not been initialized。我真的不明白为什么。应该提到我是 Kotlin 的新手并且 Android.

有什么帮助吗?

我只需要将 myWebViewthis 一起传递到 JavaScript 接口并使用 Runnable...

正在创建 JS 界面:

myWebView.addJavascriptInterface(WebAppInterface(this, myWebView), "Android")

然后在 @JavascriptInterface 函数中:

myWebView.post(Runnable {
            myWebView.loadUrl("javascript:customFunction()")
        })