我正在使用android webview加载一些网页。在我的例子中,我必须在加载网页之前插入一些javascript代码。如下所示:

//enable javascript
mWebView.getSettings().setJavaScriptEnabled(true);

//inject my js first.
//I can't inject the js onPageStarted() or onPageFinished() because I need to make  sure the js
//is injected before html loaded.
mWebView.loadUrl("javascript:MyJsCode");

//load HTML
mWebView.loadUrl("http://example.com/demos/index.html");

代码第一次运行良好,但多次运行时失败。因为html找不到我的js。
我认为,因为之前的html并不完全清楚,所以mWebView.loadUrl("javascript:MyJsCode")将myjscode注入到之前的html而不是新的html。
所以我想如果我能完全重置WebView(to clear the previous HTML),就能解决我的问题。
我试过了,都不行。
有什么建议吗?

最佳答案

虽然这有点晚了,但我提供以下信息。也许这会有帮助。…
您的问题没有特别提到使用WebChromeClient中的任何回调,但您确实提到了js,因此以下内容可能会有所帮助。在sdk level 16及以下版本中,您可以使用回调,而无需特别“清除”它们。但是,从sdk level 17开始,我注意到您必须清除事件——特别是alert(),如果您重写它,当然会导致onJSAlert()在您的WebChromeClient中被触发。在我在sdk 16及以下级别测试过的所有设备中,您可能会轻松地忽略回调,而所有这些都将按计划进行。
但是,您会注意到,当重写时,onJSAlert会在最后一个参数中传递一个JSResult对象,因此:
布尔onjsalert(webview视图、字符串url、字符串消息、jsresult结果)
我注意到jsresult对象公开了两个方法,因此:
公共方法
最终无效取消()

Handle the result if the user cancelled the dialog.

最终无效确认()
Handle a confirmation response from the user

假设在回调中返回true(表示回调使用了onjsalert事件),并且假设您使用的是sdk 16或之前的版本,那么WebView.destroy()将执行预期的操作。
然而,我注意到sdk 17(4.2.x)似乎需要进一步的证据来证明回调确实处理了事件。如果未能调用result.cancel()result.confirm(),将使您的WebView(或者更确切地说,是WebViewCore)永久无法使用。我尝试过的任何东西都不会重新唤醒WebViewCore,此后,任何WebView、new或其他文件中都不会加载任何内容。(试图解释:WebView只是一个WebViewProvider的包装类,它依次插入一个WebViewCore对象。是最后一个家伙做了所有的工作。通过漫游源代码,通过反射,你可以钻到这个对象,如果你想这样做。WebViewCore是一个WebViewCore,因此,整个应用程序只有一个static。因此,如果只有一个webviewcore被卡住,那么应用程序中的任何WebViewCore都不会在此后工作。一旦它被卡住等待,例如,要调用一个WebView方法,它将被卡住,直到应用程序被破坏(即,即使暂停/恢复应用程序也没有效果)。即使直接在JSResult上调用destroy(),通过反射获得的访问也是无效的。注意:在WebViewCore上调用destroy()与在WebView上调用destroy()有副作用,但这也没有任何帮助)。
所以,症状是
创建WebViewCore
一些聪明的js运行,可能调用alert()
WebView重写方法中处理alert()。
您无法调用onJsAlertresult.confirm()
你破坏了result.cancel()
此后,应用程序中的noWebView将加载任何内容。
好消息是,如果您确定通过调用适当的jsresult方法来“清除”您覆盖的任何回调中的事件,那么WebView不会永久停止,您的应用程序将很高兴。

08-18 16:43