WebView离线HTML嵌入视频无网络错误的自定义处理问询
解决WebView无网络时嵌入视频错误提示替换问题
嘿,这个问题我之前帮人处理过,其实有两个靠谱的方案,看你更适合哪种:
方案一:修改本地HTML,给视频添加自定义 fallback 内容
这个方案最直接——既然你的HTML是本地离线的,直接修改它的结构就能实现需求,不需要动Android端的代码。
针对原生
如果你的视频是用原生<video>标签嵌入的,直接在标签里添加加载失败时显示的自定义内容:
<video controls width="100%"> <source src="your-video-url.mp4" type="video/mp4"> <!-- 这里是自定义的无网络/加载错误提示 --> <div style="padding:20px; text-align:center; background:#f5f5f5; border:1px solid #ddd;"> <p>📺 当前无网络,视频无法加载</p> <p>请连接网络后重试</p> </div> </video>
针对iframe嵌入的第三方视频
如果是用<iframe>嵌入的第三方平台视频(比如YouTube、B站等),可以给它套一个容器,再用JS检测网络状态或加载错误来显示自定义提示:
<!-- 给每个视频套一个容器 --> <div class="video-container"> <iframe src="your-video-embed-url" frameborder="0" allowfullscreen></iframe> <!-- 初始隐藏的自定义提示 --> <div class="video-fallback" style="display:none; padding:20px; text-align:center; background:#f5f5f5; border:1px solid #ddd;"> <p>📺 当前无网络,视频无法加载</p> <p>请连接网络后重试</p> </div> </div> <script> // 页面加载时先检查网络状态 function checkNetwork() { if (!navigator.onLine) { // 无网络时隐藏iframe,显示提示 document.querySelectorAll('.video-container iframe').forEach(iframe => { iframe.style.display = 'none'; iframe.nextElementSibling.style.display = 'block'; }); } } // 监听网络状态变化 window.addEventListener('online', checkNetwork); window.addEventListener('offline', checkNetwork); // 监听iframe加载错误(即使有网络也可能加载失败) document.querySelectorAll('.video-container iframe').forEach(iframe => { iframe.addEventListener('error', () => { iframe.style.display = 'none'; iframe.nextElementSibling.style.display = 'block'; }); }); // 初始化执行一次 window.onload = checkNetwork; </script>
方案二:通过Android WebViewClient拦截错误,注入JS替换内容
如果不方便修改本地HTML,或者想在Android端统一处理所有视频错误,可以通过自定义WebViewClient来实现。
步骤1:修改你的WebViewClientClass
重写错误回调方法,检测网络状态和视频加载错误,然后注入JS替换错误区域:
public class WebViewClientClass extends WebViewClient { @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); // 判断是否是视频资源或无网络状态 if (isVideoResource(failingUrl) || !isNetworkAvailable(view.getContext())) { // 注入JS替换所有视频元素为自定义提示 String customFallbackJs = "javascript:(function(){" + "var videoElements = document.querySelectorAll('video, iframe');" + "for(let i = 0; i < videoElements.length; i++){" + " const parent = videoElements[i].parentNode;" + " const fallbackDiv = document.createElement('div');" + " fallbackDiv.style.padding = '20px';" + " fallbackDiv.style.textAlign = 'center';" + " fallbackDiv.style.background = '#f5f5f5';" + " fallbackDiv.style.border = '1px solid #ddd';" + " fallbackDiv.innerHTML = '<p>📺 当前无网络,视频无法加载</p><p>请连接网络后重试</p>';" + " parent.replaceChild(fallbackDiv, videoElements[i]);" + "}" + "})()"; view.loadUrl(customFallbackJs); } } // 判断URL是否是视频相关资源 private boolean isVideoResource(String url) { if (url == null) return false; String lowerUrl = url.toLowerCase(); return lowerUrl.contains(".mp4") || lowerUrl.contains(".avi") || lowerUrl.contains(".mov") || lowerUrl.contains("youtube") || lowerUrl.contains("vimeo"); } // 检测设备网络是否可用 private boolean isNetworkAvailable(Context context) { ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo activeNetwork = connManager.getActiveNetworkInfo(); return activeNetwork != null && activeNetwork.isConnected(); } }
步骤2:添加网络权限
别忘了在AndroidManifest.xml中添加获取网络状态的权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
两种方案的选择
- 如果你的离线HTML是可以修改的,方案一更简单,兼容性也更好;
- 如果无法修改HTML,或者需要统一管理所有视频的错误提示,方案二更合适。
内容的提问来源于stack exchange,提问作者Ali




