最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Android webview not loading URL for second time - Stack Overflow

programmeradmin0浏览0评论

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
Add a ment  | 

5 Answers 5

Reset to default 1

I 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)
发布评论

评论列表(0)

  1. 暂无评论