Android webview 第二次没有加载 URL [英] Android webview not loading URL for second time

查看:87
本文介绍了Android webview 第二次没有加载 URL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有加载到 web 视图中的动态 URL.我使用 WebChromeClient 来处理 java 脚本事件,因为我需要根据 onJsAlert() 中来自 javascript 的事件重定向用户.网页是第一次加载.当我返回并加载相同的 url 时,它的加载.但是,当我完成操作并收到 javascript 事件时,我开始了一个新活动并完成了 webview 活动.现在,当我加载另一个 URL 时,它没有加载.当我终止应用程序并导航到 webview 活动时,它会再次加载.

以下是我对 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.setHorizo​​ntalScrollBarEnabled(false);

这是我用来显示进度对话框的 WebViewClient

<预><代码>公共类 myWebClient 扩展了 WebViewClient {@覆盖public void onPageStarted(WebView view, String url, Bitmap favicon) {//TODO 自动生成的方法存根super.onPageStarted(view, url, favicon);}@覆盖public boolean shouldOverrideUrlLoading(WebView view, String url) {如果 (((BaseActivity) 活动).checkConnection()) {//TODO 自动生成的方法存根progressBar.setVisibility(View.VISIBLE);view.loadUrl(url);}返回真;}@覆盖public void onPageFinished(WebView view, String url) {//TODO 自动生成的方法存根super.onPageFinished(view, url);progressBar.setVisibility(View.GONE);}@覆盖public void onReceivedError(WebView 视图,WebResourceRequest 请求,WebResourceError 错误){super.onReceivedError(view, request, error);progressBar.setVisibility(View.GONE);}}

这就是我处理 JS 事件的方式

<预><代码>私有类 MyJavaScriptChromeClient 扩展了 WebChromeClient {@覆盖public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {//检查支付成功/失败的消息Log.i("message",message);if (message.equals("支付失败")){dgAlert("付款失败");}else if (message.equals("支付成功")){dgAlert("支付成功");}返回真;}}

这就是我点击警报对话框上的确定"按钮所做的

Intent intent=new Intent(Payment.this, DashBoardActivity.class);开始活动(意图);如果 (message.equals(Constants.CANCELLED)) {活动.finishAffinity();System.exit(0);} 别的活动.完成();

解决方案

我遇到了同样的问题,多次重新加载 url 解决了该问题,在 WebViewClient 中重写以下方法特别是错误相关的方法并在遇到错误时重新加载 url错误,保持最大重载阈值以避免无限重载错误循环.还要确保在使用后正确释放/销毁 webview 以避免内存泄漏.

override fun onReceivedSslError(视图:WebView?,处理程序:SslErrorHandler,错误:SslError?){Log.e("webview", "onReceivedSslError")handler.proceed()//忽略 SSL 证书错误}覆盖 fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {super.onPageStarted(view, url, favicon)Log.e("webview", "onPageStarted")onPageLoadStarted = 真progressBar.visibility = View.VISIBLE}覆盖乐趣 onReceivedError(视图:WebView?,请求:WebResourceRequest?,错误:WebResourceError?){super.onReceivedError(查看,请求,错误)Log.e("webview", "onReceivedError" + error.toString())progressBar.visibility = View.GONE重新加载()}覆盖乐趣 onReceivedHttpError(视图:WebView?,请求:WebResourceRequest?,错误响应:WebResourceResponse?){super.onReceivedHttpError(view, request, errorResponse)Log.d("webview", "onReceivedHttpError" + errorResponse?.toString())progressBar.visibility = View.GONE重新加载()}

并为活动或片段添加重新加载功能并覆盖生命周期方法,如下所示

var reloadCount=0const VAL MAX_RELOAD_TRY = 6有趣的重新加载(){if ((reloadCount <= MAX_RELOAD_TRY)) {重载计数++webView?.clearCache(true);webView?.clearView();webView?.clearHistory()webView?.resumeTimers()webView?.reload()}}覆盖乐趣 onPause() {super.onPause()webView?.onPause()}覆盖乐趣 onResume() {super.onResume()webView?.onResume()}覆盖乐趣 onBackPressed() {webView?.let {如果 (it.canGoBack()) {it.goBack()} 别的 {super.onBackPressed()}} ?: 跑 {super.onBackPressed()}}覆盖乐趣 onDestroy() {super.onDestroy()Log.d("onDestroy", "onDestroy")销毁WebView()}私人乐趣 destroyWebView() {Log.d("destroyWebView", "destroyWebView");//确保在执行任何操作之前从其父视图中删除 WebView.webView?.clearHistory()//注意:清除RAM缓存,如果传递true,它也会清除磁盘缓存.//如果您还有其他 WebView 还活着,则传递 true 可能不是一个好主意.webView?.clearCache(true)//加载空白页面是可选的,但会确保 WebView 在您销毁它时不执行任何操作.//webView?.loadUrl("about:blank")//注意:这会暂停所有 WebView 的 JavaScript 执行,//如果您还有其他 WebViews 还活着,请不要使用.//如果你在调用这个之后创建另一个 WebView,//确保调用 mWebView.resumeTimers().webView?.pauseTimers()webView?.removeAllViews()webViewContainerRL?.removeAllViews()webView?.destroy()webViewClient = nullwebChromeClient = null网络视图 = 空}

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 complete 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 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

    }

这篇关于Android webview 第二次没有加载 URL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆