当前位置: 首页 > 知识库问答 >
问题:

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

柴琦
2023-03-14

作为一个示例,让我们假设在一个项目中,我在我的主要活动中使用了一个WebView实例,加载一个本地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也,从那里我想调用Android.get状态()在我的超文本标记语言文件:

<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>

到目前为止,我想明白为什么这行不通了。从我从这样或这样的答案中了解到的,尤其是在WebView的留档中,我知道JavascriptInterface和WebView在不同的线程上运行,所以像setState()这样的东西不会被定义。到目前为止,我已经尝试使用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!')")
                    }
                }
            )
    }

然而,这(以及处理程序的使用)给了我:E/AndroidRuntime:FATAL异常:JavaBridgelateinit属性myWebView尚未初始化。我真的不明白为什么。应该提到我是Kotlin和Android的新手。

有什么帮助吗?


共有1个答案

马才
2023-03-14

我只需要将myWebViewthis一起传递到JavaScript界面,然后使用Runnable。。。

创建JS接口

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

然后在一个@JavascriptInterface函数中:

myWebView.post(Runnable {
            myWebView.loadUrl("javascript:customFunction()")
        })
 类似资料:
  • 我有一个相同错误的崩溃报告,就像这个问题中的一样:同一线程上的WebView方法错误 建议创建Runnable()。 我不明白为什么这能解决问题。该错误表示相同线程上的Webview方法,但答案建议在UI-Thread(主线程)上创建该方法。但是UI-Thread不是唯一的线程吗?有人能详细解释整个过程吗(考虑到我在构造函数的每个活动中创建了一个新的Webview)? 实现Javascript函数

  • 问题内容: 如何创建从我的网站到UIWebView的JavascriptInterface通道? Android中的示例: 我想从这个JavascriptInterface绘制方法,例如: 要么 我能怎么做? 问题答案: 对于WKWebView:源在这里 的JavaScript 迅速 对于UIWebView:此处来源 HTML中的JavaScript 迅速

  • 我在我的应用程序中有一个活动,其中有一个Webview,可以打开提供给它的URL,然后重定向到网站的登录页。我面临的问题是,一旦用户在登录页上,重定向就是相同的页面重定向,即如果登录页是 www.example。通信/着陆 重定向是 www.example。com/landing/#其他_页面 它不调用 onPageStarted(WebView视图、字符串url、位图favicon) 但是 网页

  • 问题内容: 我正在使用Selenium python Webdriver来浏览某些页面。我想在加载和执行任何其他Javascript代码之前向页面中注入JavaScript代码。另一方面,我需要将我的JS代码作为该页面的第一个JS代码执行。Selenium有办法做到吗? 我用谷歌搜索了几个小时,但找不到合适的答案! 问题答案: 如果您无法修改页面内容,则可以使用代理或在浏览器中安装的扩展程序中使用

  • 本文向大家介绍Android中替换WebView加载网页失败时的页面,包括了Android中替换WebView加载网页失败时的页面的使用技巧和注意事项,需要的朋友参考一下 我们用webView去请求一个网页链接的时候,如果请求网页失败或无网络的情况下,它会返回给我们这样一个页面,如下图所示:   上面这个页面就是系统自带的页面,你觉得是不是很丑?反正小编本人觉得非常丑,很难看,于是乎小编就在想能不