问题描述
我有加载到 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.setHorizontalScrollBarEnabled(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
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!