webview 处理

 @Override
    public void onPageFinished(WebView view, String url) {
        view.getSettings().setBlockNetworkImage(false);
      
        webViewClient.onPageFinished(view, url);
    }
    
     @Override
    public void onPageCommitVisible(WebView view, String url) {
        super.onPageCommitVisible(view, url);
    }
    
     public void onReceivedError(WebView view, int errorCode,
            String description, String failingUrl) {
            
             public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
        if (request.isForMainFrame()) {
        
        
         public void onReceivedHttpError(
            WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
    }
    
    
    public class WebAppInterface {
    Context mContext;

    /** Instantiate the interface and set the context */
    WebAppInterface(Context c) {
        mContext = c;
    }

    /** Show a toast from the web page */
    @JavascriptInterface
    public void showToast(String toast) {
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
    }
    
    
     WebSettings webSetting = this.getSettings();
        webSetting.setJavaScriptEnabled(true);
        webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
        webSetting.setAllowFileAccess(true);
        webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        webSetting.setSupportZoom(true);
        webSetting.setUseWideViewPort(true);
        webSetting.setSupportMultipleWindows(true);
        webSetting.setDomStorageEnabled(true);
        webSetting.setAppCacheEnabled(false);
        webSetting.setGeolocationEnabled(true);
        webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
        webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
        webSetting.setDefaultTextEncodingName("utf-8");
        webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            webSetting.setMixedContentMode(0);
        }
        webSetting.setUserAgentString(webSetting.getUserAgentString());
        webSetting.setAllowFileAccess(true);
        //                webSetting.setBlockNetworkImage(true);//同步请求图片
        webSetting.setBuiltInZoomControls(false);
        webSetting.setLoadWithOverviewMode(true);
        webSetting.setDatabaseEnabled(true);
        webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
    
    
}

    window.aaaa.openNotice();
    webview.loadUrl("javascript:getImgSrc()");
     webview.addJavascriptInterface(WebAppInterface, "aaaa");
        
        webview.loaddata("","text/html"):
     setWebChromeClient  
       @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                if (getActivity() != null && getActivity().isFinishing()) {
                    if (result != null) {
                        result.cancel();
                    }
                    return true;
                }
                return super.onJsAlert(view, url, message, result);
            }

            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
                if (getActivity() != null && getActivity().isFinishing()) {
                    if (result != null) {
                        result.cancel();
                    }
                    return false;
                }
                return super.onJsPrompt(view, url, message, defaultValue, result);
            }
            
            
            Android6.0以上判断404或者500
重写WebViewClient()的onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse)方法,通过状态码判断;
Android 6.0以下判断404或者500
重写WebChromeClient()的onReceivedTitle(WebView view, String title)方法,通过标题是否包含“404”,"500","error"等字符判断;

断网或者超时判断(注意404或者500等其他非断网超时情况不走这个方法)
重写WebViewClient() 的onReceivedError(WebView view, int errorCode, String description, String failingUrl)


1.先看404的情况,果然进了onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse)方法,但是问题来了,正常的页面也返回404,去查了一下官方文档,发现一个请求页面任何资源的加载都会引发HTTP ERROR都会引起该方法的回调(例如页面的内部请求图标,或者图片等),
解决方法:
通过判断当前请求的url地址request.getUrl()是否等于根url,但是有一些请求地址通过request.getUrl()获取的url不等于根url,这个目前还没找到好的办法;
3.2 6.0以下系统测试
问题
1.先看404的情况,onReceivedTitle,这个方法还是有个别服务返回的标题不包含“404”,"500","error"等字符,暂时也没有好的解决方法;
3.3 超时测试
问题:
onReceivedError监听超时情况,需要很长时间,而webview请求的超时时间也不能控制,太影响用户体验;
解决办法:
在WebViewClient的onPageStarted(改方法是每个请求地址开始时调用),开启一个线程,设置一个时间监听,当超过这个时间,加载超时页面;

<think> 根据用户的问题,用户想知道在Android WebView处理onReceivedTitle回调时,当标题为"Webpage not available"的解决方案。 首先,我们需要理解这个回调的作用:当WebView加载网页时,如果网页设置了标题(即HTML中的<title>标签),就会触发onReceivedTitle回调,并返回标题字符串。然而,当网页加载失败(例如网络错误、页面不存在等)时,WebView可能会显示一个错误页面,并且这个错误页面的标题可能是"Webpage not available"(或者类似的提示)。用户希望在这种情况下能够捕获这个标题并进行处理。 通常,我们可以通过重写WebViewClient的onReceivedTitle方法来实现。在这个回调中,我们可以检查标题字符串,如果检测到是错误提示(如"Webpage not available"),则执行相应的错误处理逻辑。 但是,需要注意的是,不同的设备或系统版本可能显示的错误标题可能有所不同,因此我们需要考虑兼容性。此外,仅仅依靠标题来判断页面加载是否失败可能不够可靠,因为有些正常的网页也可能设置类似的标题。因此,更常见的做法是结合其他错误处理方法,例如onReceivedError回调。 不过,用户的问题特别提到了onReceivedTitle回调,所以我们将重点放在这个回调上。 步骤: 1. 自定义一个WebViewClient,重写onReceivedTitle方法。 2. 在onReceivedTitle中,检查title字符串是否包含错误提示(如"Webpage not available"),如果是,则执行相应的处理(例如显示自定义错误页面,或者进行其他操作)。 3. 注意:由于错误标题可能因设备和系统版本而异,可能需要收集多种错误标题字符串进行匹配,或者考虑使用正则表达式匹配。 同时,我们也可以考虑结合onReceivedError回调(在WebViewClient中)来处理错误,因为onReceivedError提供了更具体的错误信息(错误码和描述)。这样,我们可以更准确地判断页面加载是否失败。 但是,用户只提到了onReceivedTitle,所以我们先给出基于onReceivedTitle的解决方案。 示例代码: ```java webView.setWebViewClient(new WebViewClient() { @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); // 检查标题是否为错误提示 if (title != null && title.contains("Webpage not available")) { // 执行错误处理,例如加载自定义错误页面 // 注意:这里我们只是简单示例,实际中可能需要更复杂的判断 view.loadUrl("file:///android_asset/error.html"); } } }); ``` 然而,上述方法有一个问题:在加载错误页面时,我们可能又会触发onReceivedTitle回调,导致循环。因此,我们需要避免这种情况,例如设置一个标志位,或者确保自定义错误页面的标题不是错误字符串。 更推荐的做法是同时使用onReceivedError回调来处理错误,因为这样更准确。在onReceivedError回调中,我们可以标记一个错误状态,然后在onReceivedTitle中根据这个状态来判断是否处理。 结合onReceivedError的改进方案: ```java private boolean isErrorPage = false; webView.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); // 标记发生了错误 isErrorPage = true; // 在这里也可以直接处理错误,比如加载自定义错误页面 // view.loadUrl("file:///android_asset/error.html"); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // 页面加载完成,重置错误标记 isErrorPage = false; } @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); if (isErrorPage) { // 如果已经标记为错误页面,那么即使标题是错误信息,我们也不处理,因为已经在onReceivedError中处理了 // 或者,我们可以在这里再次确认,但通常不需要 return; } // 如果非错误状态,但标题是错误提示,这种情况很少,因为正常页面不应该有错误标题 if (title != null && title.contains("Webpage not available")) { // 如果没有触发onReceivedError,但标题是错误提示,可能是其他情况 // 执行错误处理 view.loadUrl("file:///android_asset/error.html"); } } }); ``` 但是,需要注意的是,onReceivedError回调在Android 6.0(API 23)及以上版本被废弃,取而代之的是onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)方法。因此,为了兼容,我们需要重写两个onReceivedError方法(针对不同API版本)。 考虑到用户问题,我们主要关注标题的处理,因此我们也可以选择只使用onReceivedTitle,但要谨慎处理,避免循环。 另一种方法是:在onReceivedTitle中,如果检测到错误标题,则立即加载自定义错误页面,并忽略后续的标题变化(因为自定义错误页面会有自己的标题)。但这样可能不够健壮。 综上所述,我们建议结合使用onReceivedError(兼容不同版本)和onReceivedTitle,以更可靠地检测错误。 针对用户的问题,我们给出一个以onReceivedTitle为主的解决方案,同时考虑到错误处理的健壮性。 最终,我们提供一个相对完整的示例,包括对API23以上和以下的支持: ```java private boolean isErrorPage = false; webView.setWebViewClient(new WebViewClient() { // 对于API 23(Marshmallow)以下 @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); handleError(); } // 对于API 23及以上 @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); if (request.isForMainFrame()) { // 如果是主框架的错误 handleError(); } } private void handleError() { isErrorPage = true; // 在这里可以加载自定义错误页面,或者记录错误状态 } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); isErrorPage = false; } @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); // 如果已经处理了错误(通过onReceivedError),则不需要再根据标题处理 if (isErrorPage) { return; } // 如果标题包含错误信息 if (title != null && title.equals("Webpage not available")) { // 为了防止误判,我们可以检查当前URL是否是之前加载的URL(如果有保存的话) // 或者直接处理 handleError(); // 加载自定义错误页面 view.loadUrl("file:///android_asset/error.html"); } } }); ``` 注意:上述代码中,我们在onReceivedTitle中再次调用了handleError(),这可能会重复处理错误。为了避免重复,我们可以设置一个标志位,确保只处理一次。 另外,在onReceivedTitle中加载错误页面可能会重新触发页面加载,因此需要确保不会因此进入死循环。我们加载的错误页面应该有一个正常的标题(不是错误标题),这样就不会再次触发错误处理。 另外,用户可能需要自定义错误页面,并在错误页面中提供重试按钮等。 总结解决方案: 1. 通过重写WebViewClient的onReceivedTitle方法,检测到特定错误标题(如"Webpage not available")时,加载自定义错误页面。 2. 为了更可靠,结合onReceivedError回调(兼容不同API版本)来标记错误状态,避免误判。 3. 在自定义错误页面中,避免使用与错误相同的标题,防止循环。 但是,请注意,错误标题可能因设备或系统版本而异,因此可能需要适配多种字符串,例如: - "Webpage not available" - "网页不可用" - 等等 因此,在检查标题时,可以检查多个可能的字符串,或者使用正则表达式匹配。 最后,如果用户希望更精确地处理错误,建议主要依赖onReceivedError回调,而将onReceivedTitle作为辅助手段。 根据引用[1]中,我们看到一个Activity的配置,如果用户需要在WebView处理错误,也可以考虑在WebView所在Activity中控制错误显示。 以上方案供用户参考。 </think> 在Android WebView处理`onReceivedTitle`回调出现"Webpage not available"标题的解决方案,通常表示网页加载失败或网络不可用。以下是系统性的解决方法和优化建议: ### 解决方案 #### 1. 检测并处理加载错误 在`WebViewClient`中同时实现`onReceivedError`方法捕获具体错误代码: ```java webView.setWebViewClient(new WebViewClient() { @Override public void onReceivedTitle(WebView view, String title) { if ("Webpage not available".equals(title)) { // 显示自定义错误页 view.loadUrl("file:///android_asset/error.html"); } } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { // 记录错误类型(如 ERROR_TIMEOUT, ERROR_CONNECT) showCustomErrorPage(errorCode); } @Override public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) { // 处理HTTP错误(如404) } }); ``` #### 2. 自定义错误页面 在assets目录创建`error.html`,提供友好提示和重试按钮: ```html <!DOCTYPE html> <html> <body> <h2>网络连接失败</h2> <button onclick="retry()">重新加载</button> <script> function retry() { Android.retryLoad(); // 调用Android接口 } </script> </body> </html> ``` #### 3. 添加网络状态检查 在加载前验证网络连接: ```java private boolean isNetworkAvailable() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); return netInfo != null && netInfo.isConnected(); } // 使用示例 if (isNetworkAvailable()) { webView.loadUrl("https://example.com"); } else { showNetworkErrorDialog(); } ``` #### 4. 优化WebView配置 ```java // 启用缓存和DOM存储 webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT); webView.getSettings().setDomStorageEnabled(true); // 设置超时重试机制 webView.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(...) { new Handler().postDelayed(() -> webView.reload(), 3000); } }); ``` #### 5. 处理重定向逻辑 在`error.html`中通过JS桥接实现重试: ```java webView.addJavascriptInterface(new Object() { @JavascriptInterface public void retryLoad() { runOnUiThread(() -> webView.reload()); } }, "Android"); ``` ### 关键注意事项 1. **多错误场景覆盖**: - 连接超时:增加`webView.getSettings().setLoadsImagesAutomatically(false)`减少流量消耗 - HTTPS错误:实现`onReceivedSslError`处理证书问题 - 资源加载失败:使用`onLoadResource`监控资源加载 2. **用户体验优化**: ```java // 显示加载进度 webView.setWebChromeClient(new WebChromeClient() { @Override public void onProgressChanged(WebView view, int progress) { progressBar.setProgress(progress); } }); ``` 3. **AndroidManifest权限配置**: ```xml <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> ``` ### 替代方案 对于SPA应用(如Vue/React),推荐使用前端路由错误处理: ```javascript // Vue路由示例 router.onError((error) => { if (error.message.includes("Failed to fetch dynamically")) { router.push("/network-error"); } }) ``` > 通过组合使用`onReceivedTitle`检测、`onReceivedError`精确分类错误、自定义错误页面和网络状态监控,可系统性地解决"Webpage not available"问题,同时提升用户体验[^1][^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值