I have dynamic URL that I load into a webview. I have used a WebChromeClient to handle java script events as I need to redirect the user depending on the events from the javascript in onJsAlert(). The webpage is loading for the first time. When I go back and load the same url, its loading. But, when I plete the action and receive the javascript event, I'm starting a new activity and finishing the webview activity. Now, when I load another URL, its not loading. When I kill the app and navigate to the webview activity, its loading again.
Below are my settings for the webview
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setDisplayZoomControls(false);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setAppCacheEnabled(false);
webView.setWebViewClient(new myWebClient());
webView.setWebChromeClient(new MyJavaScriptChromeClient());
webView.loadUrl(signatureURL);
webView.setHorizontalScrollBarEnabled(false);
This is the WebViewClient I'm using to show progress dialog
public class myWebClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (((BaseActivity) activity).checkConnection()) {
// TODO Auto-generated method stub
progressBar.setVisibility(View.VISIBLE);
view.loadUrl(url);
}
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
progressBar.setVisibility(View.GONE);
}
}
This is how I'm handing JS events
private class MyJavaScriptChromeClient extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
//Check message for success/failure of payment
Log.i("message",message);
if (message.equals("Payment Fail")){
dgAlert("Payment Failed");
}
else if (message.equals("Payment Success")){
dgAlert("Payment Success");
}
return true;
}
}
This is what I'm doing on tapping OK button on the Alert Dialog
Intent intent=new Intent(Payment.this, DashBoardActivity.class);
startActivity(intent);
if (message.equals(Constants.CANCELLED)) {
activity.finishAffinity();
System.exit(0);
} else
activity.finish();
I have dynamic URL that I load into a webview. I have used a WebChromeClient to handle java script events as I need to redirect the user depending on the events from the javascript in onJsAlert(). The webpage is loading for the first time. When I go back and load the same url, its loading. But, when I plete the action and receive the javascript event, I'm starting a new activity and finishing the webview activity. Now, when I load another URL, its not loading. When I kill the app and navigate to the webview activity, its loading again.
Below are my settings for the webview
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setDisplayZoomControls(false);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setAppCacheEnabled(false);
webView.setWebViewClient(new myWebClient());
webView.setWebChromeClient(new MyJavaScriptChromeClient());
webView.loadUrl(signatureURL);
webView.setHorizontalScrollBarEnabled(false);
This is the WebViewClient I'm using to show progress dialog
public class myWebClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (((BaseActivity) activity).checkConnection()) {
// TODO Auto-generated method stub
progressBar.setVisibility(View.VISIBLE);
view.loadUrl(url);
}
return true;
}
@Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
progressBar.setVisibility(View.GONE);
}
}
This is how I'm handing JS events
private class MyJavaScriptChromeClient extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
//Check message for success/failure of payment
Log.i("message",message);
if (message.equals("Payment Fail")){
dgAlert("Payment Failed");
}
else if (message.equals("Payment Success")){
dgAlert("Payment Success");
}
return true;
}
}
This is what I'm doing on tapping OK button on the Alert Dialog
Intent intent=new Intent(Payment.this, DashBoardActivity.class);
startActivity(intent);
if (message.equals(Constants.CANCELLED)) {
activity.finishAffinity();
System.exit(0);
} else
activity.finish();
Share
Improve this question
asked Mar 28, 2019 at 13:57
rkorko
2134 silver badges11 bronze badges
5
- I have tried by clearing history before loading URL but it didn't help. – rko Commented Mar 29, 2019 at 8:45
- I'm also stuck with this one. Any luck? – André Herculano Commented Apr 10, 2019 at 16:54
- facing the same issue? any solution? – Pradip Vadher Commented Jul 19, 2019 at 8:51
- same issue for api 28 – BekaBot Commented Aug 13, 2019 at 5:19
- any update on this issue? – Nithin Commented Feb 12, 2020 at 9:33
5 Answers
Reset to default 1I had the same issue, reloading the url multiple times fixed the issue, override following method specially error related method in the WebViewClient and reload the url if you encounter an error, keep a max reload threshold to avoid infinite reload error loop. Also make sure webview is properly released/destroyed after use to avoid memory leak.
override fun onReceivedSslError(
view: WebView?,
handler: SslErrorHandler,
error: SslError?
) {
Log.e("webview", "onReceivedSslError")
handler.proceed() // Ignore SSL certificate errors
}
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
Log.e("webview", "onPageStarted")
onPageLoadStarted = true
progressBar.visibility = View.VISIBLE
}
override fun onReceivedError(
view: WebView?,
request: WebResourceRequest?,
error: WebResourceError?
) {
super.onReceivedError(view, request, error)
Log.e("webview", "onReceivedError" + error.toString())
progressBar.visibility = View.GONE
reload()
}
override fun onReceivedHttpError(
view: WebView?,
request: WebResourceRequest?,
errorResponse: WebResourceResponse?
) {
super.onReceivedHttpError(view, request, errorResponse)
Log.d("webview", "onReceivedHttpError" + errorResponse?.toString())
progressBar.visibility = View.GONE
reload()
}
and Add a reload function to activity or fragment and override lifecycle method like below
var reloadCount=0
const val MAX_RELOAD_TRY = 6
fun reload() {
if ((reloadCount <= MAX_RELOAD_TRY)) {
reloadCount++
webView?.clearCache(true);
webView?.clearView();
webView?.clearHistory()
webView?.resumeTimers()
webView?.reload()
}
}
override fun onPause() {
super.onPause()
webView?.onPause()
}
override fun onResume() {
super.onResume()
webView?.onResume()
}
override fun onBackPressed() {
webView?.let {
if (it.canGoBack()) {
it.goBack()
} else {
super.onBackPressed()
}
} ?: run {
super.onBackPressed()
}
}
override fun onDestroy() {
super.onDestroy()
Log.d("onDestroy", "onDestroy")
destroyWebView()
}
private fun destroyWebView() {
Log.d("destroyWebView", "destroyWebView");
// Make sure you remove the WebView from its parent view before doing anything.
webView?.clearHistory()
// NOTE: clears RAM cache, if you pass true, it will also clear the disk cache.
// Probably not a great idea to pass true if you have other WebViews still alive.
webView?.clearCache(true)
// Loading a blank page is optional, but will ensure that the WebView isn't doing anything when you destroy it.
//webView?.loadUrl("about:blank")
// NOTE: This pauses JavaScript execution for ALL WebViews,
// do not use if you have other WebViews still alive.
// If you create another WebView after calling this,
// make sure to call mWebView.resumeTimers().
webView?.pauseTimers()
webView?.removeAllViews()
webViewContainerRL?.removeAllViews()
webView?.destroy()
webViewClient = null
webChromeClient = null
webView = null
}
For me nothing worked, just solution from here WebView doesn't load my HTML the second time?.
In Kotlin, I put this in my refresh button:
val handler = Handler()
handler.postDelayed(Runnable {
myWebview.loadUrl("https://www.example.")
}, 10)
or with binding, one line:
binding.myWebview.handler.postDelayed({binding.myWebview.loadUrl("https://www.example.")},10)
I know it's late but it might help someone else. You can try to return false in the WebChromeClient like this :
private class MyJavaScriptChromeClient extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
//Check message for success/failure of payment
Log.i("message",message);
if (message.equals("Payment Fail")){
dgAlert("Payment Failed");
}
else if (message.equals("Payment Success")){
dgAlert("Payment Success");
}
return false;
}
}
It will work fine.
In my case this was caused by an unnecessary webView.reload();
placed after webView.loadUrl("https://...")
The reload()
appears to reinstate the previous URL, so I removed it.
ThomasV answer worked for me, But in case you face the deperecation!
Handler(Looper.getMainLooper()).postDelayed({
// Your Code
myWebview.loadUrl("https://www.example.")
}, 100)