我正在使用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()。您无法调用
onJsAlert
或result.confirm()
你破坏了
result.cancel()
此后,应用程序中的no
WebView
将加载任何内容。好消息是,如果您确定通过调用适当的jsresult方法来“清除”您覆盖的任何回调中的事件,那么
WebView
不会永久停止,您的应用程序将很高兴。