我想用JS修改Android WebView
页面加载(在此示例中只显示来自JS的提醒):
private static final String script2 = "alert('hello world');";
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Toast.makeText(MainActivity.this, "Alert from js:\n" + message, Toast.LENGTH_LONG).show();
return true; // ANSWER found:should return false in order NOT to freeze
}
});
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
getSupportActionBar().setTitle("Finishing ");
getSupportActionBar().setSubtitle(url);
if (cbScript2.isChecked()) { // true
runScript(script2);
}
getSupportActionBar().setTitle("Finished");
}
});
private void runScript(String script) {
if (cbApi19.isChecked()) // true
webView.evaluateJavascript(script, null);
else
webView.loadUrl("javascript:" + script);
}
在评估javascript(使用evaluateJavascript
或.loadUrl("javascript:" ...
)后,页面变得无法响应 - 无法滚动页面或点击链接。
根据docs:evaluateJavascript
在当前显示的页面的上下文中异步评估JavaScript。
为什么要冻结页面?我可以执行我的JS而不会对页面行为产生任何影响吗?
答案 0 :(得分:0)
原因是我使用WebChromeClient
和alert
作为检查JS工作的方法。我正在返回true
,在更改为false
后,它不再冻结(使用源代码更新问题并在可修复的地方发表评论)。
文档:
/**
* Tell the client to display a javascript alert dialog. If the client
* returns true, WebView will assume that the client will handle the
* dialog. If the client returns false, it will continue execution.
* @param view The WebView that initiated the callback.
* @param url The url of the page requesting the dialog.
* @param message Message to be displayed in the window.
* @param result A JsResult to confirm that the user hit enter.
* @return boolean Whether the client will handle the alert dialog.
*/
public boolean onJsAlert(WebView view, String url, String message,
JsResult result) {
return false;
}
答案 1 :(得分:0)
派对有点晚,但希望能帮助遇到同样问题的其他人。
当您尝试在本机中处理JS警报时,会出现问题,并且不会通过警报通知JS您的最终操作。用户处理本机警报后,应使用JsAlert
或cancel
操作调用confirm
变量。
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
new AlertDialog.Builder(this)
.setMessage(message)
.setPositiveButton(R.string.ok, (dialog, which) -> {
dialog.dismiss();
result.cancel();
}).setCancelable(false)
.show();
return true;
}