Android无网络错误页面仅首次启动生效问题咨询
解决WebView无网时缓存优先不显示错误页的问题
我来帮你搞定这个头疼的问题!
问题根源
你遇到的情况是WebView的默认缓存机制在搞鬼:
- 首次无网启动时,WebView还没有目标页面的本地缓存,所以加载失败触发
onReceivedError回调,成功显示错误页。 - 但只要你之前在有网状态下加载过目标页面,WebView就会把页面内容缓存到本地。第二次无网启动时,它会直接读取缓存内容,完全不会触发错误回调,自然就跳过了你的错误页面。
两种解决方案
方案一:强制禁用缓存(简单直接)
如果你不需要WebView的缓存功能,可以在初始化WebView时直接设置不使用缓存,这样无论有没有缓存,WebView都会尝试从网络加载,无网时就会触发错误回调:
// 获取WebView设置 WebSettings webSettings = mywebview.getSettings(); // 强制不使用缓存,每次都从网络请求 webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE); // 保留你原来的错误回调逻辑 mywebview.setWebViewClient(new WebViewClient(){ @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { mywebview.loadUrl("file:///android_asset/error.html"); } // 适配Android 7.0+的新回调方法(兜底用) @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); // 只在主页面加载失败时显示错误页,避免子资源(如图片、CSS)失败就触发 if (request.isForMainFrame()) { mywebview.loadUrl("file:///android_asset/error.html"); } } });
缺点:有网时也不会使用缓存,可能会影响页面加载速度。
方案二:主动检查网络状态(更灵活,兼顾体验)
这种方法是在启动时先判断网络状态,主动决定加载目标页面还是错误页,同时保留缓存提升有网时的体验:
- 先写一个网络状态检查的工具方法:
private boolean isNetworkAvailable(Context context) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (connectivityManager != null) { NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo(); return activeNetworkInfo != null && activeNetworkInfo.isConnected(); } return false; }
- 初始化WebView时根据网络状态处理:
WebSettings webSettings = mywebview.getSettings(); // 有网时用默认缓存策略:优先从网络获取,无网时用缓存(但我们已经主动判断了网络状态) webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); // 主动检查网络 if (isNetworkAvailable(this)) { // 有网时正常加载目标URL mywebview.loadUrl("你的目标网页地址"); } else { // 无网直接加载错误页 mywebview.loadUrl("file:///android_asset/error.html"); } // 保留错误回调作为兜底(比如加载过程中突然断网的情况) mywebview.setWebViewClient(new WebViewClient(){ @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); if (request.isForMainFrame()) { mywebview.loadUrl("file:///android_asset/error.html"); } } });
优点:既保证无网时直接显示错误页,又能在有网时利用缓存加快加载速度,同时保留回调处理突发断网的情况。
注意事项
- 如果你使用方案二,别忘了在AndroidManifest.xml中添加网络权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
内容的提问来源于stack exchange,提问作者Mahmoud Manson
相关产品推荐
相关产品推荐

