Reputation: 20422
I'd like to modify loaded by Android WebView
page with JS (in this example just show alert from 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);
}
After evaluating javascript (using evaluateJavascript
or .loadUrl("javascript:" ...
) the page becomes unresponsive - it can't be scrolled or the links clicked.
According to the docs: evaluateJavascript
Asynchronously evaluates JavaScript in the context of the currently displayed page.
Why does it freeze the page? Can i execute my JS without any affect on the page behaviour?
Upvotes: 2
Views: 2633
Reputation: 3725
A little late to the party but hopefully will help someone else facing the same problem.
The problem occurs when you try to handle JS alert in native and do not notify JS about your final action with alert. The JsAlert
variable should be invoked with cancel
or confirm
action once user deals with native alert.
@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;
}
Upvotes: 2
Reputation: 20422
The reason was that i was using WebChromeClient
and alert
as a way to check JS is working. I was returning true
and after changing to false
it's not freezing any more (updated the question with source code and comment where it can be fixed).
Docs:
/**
* 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;
}
Upvotes: 1