menu

秋梦无痕

一场秋雨无梦痕,春夜清风冻煞人。冬来冷水寒似铁,夏至京北蟑满城。

Avatar

android中WebView加载网页出现白屏的问题

问题描述:
使用webview加载Web界面时,会出现界面白屏的情况。http下通常问题不大,通常https白屏的可能性很大,但是通常没有任何报错。

解决方案:
1、启用javascript。
2、使用setDomStorageEnabled方法来支持HTML5中的一些控件标签。【重要】
3、允许有https和http混合的内容。
4、跳过页面中的特殊url。
5、允许证书错误。
6、允许javascript错误。【重要】

AndroidManifest.xml中的权限:

<uses-permission android:name="android.permission.INTERNET" />


别的权限一般情况下不需要。

上代码:

WebView webview = findViewById(R.id.viewWeb);

WebSettings settings = webview.getSettings();
settings.setJavaScriptEnabled(true); // 启用javascript
settings.setDomStorageEnabled(true); // 支持HTML5中的一些控件标签
settings.setBuiltInZoomControls(false); // 自选,非必要
//处理http和https混合的问题
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
} else {
    settings.setMixedContentMode(WebSettings.LOAD_NORMAL);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
    // 允许javascript出错
    try {
        Method method = Class.forName("android.webkit.WebView").
                getMethod("setWebContentsDebuggingEnabled", Boolean.TYPE);
        if (method != null) {
            method.setAccessible(true);
            method.invoke(null, true);
        }
    } catch (Exception e) {
        // do nothing
    }
}

webview.setFocusable(true); // 自选,非必要
webview.setDrawingCacheEnabled(true); // 自选,非必要
webview.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); // 自选,非必要
webview.setWebChromeClient(new WebChromeClient() {
    @Override
    public void onProgressChanged(WebView view, int progress) { // 显示加载进度,自选
        TextView txtProgress = findViewById(R.id.txtProgress);
        txtProgress.setText(String.format(Locale.CHINA, "%d%%", progress));
        txtProgress.setVisibility((progress > 0 && progress < 100) ? View.VISIBLE : View.GONE);
    }

    @Override
    public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        super.onGeolocationPermissionsShowPrompt(origin, callback);
        callback.invoke(origin, true, false); // 页面有请求位置的时候需要
    }
});
webview.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        if (url.startsWith("http://") || url.startsWith("https://")) { // 4.0以上必须要加
            view.loadUrl(url);
            return true;
        }
        return false;
    }

    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        //super.onReceivedSslError(view, handler, error)
        switch (error.getPrimaryError()) {
            case SslError.SSL_INVALID: // 校验过程遇到了bug
            case SslError.SSL_UNTRUSTED: // 证书有问题
                handler.proceed();
            default:
                handler.cancel();
        }
    }
});
webview.loadUrl("https://ifyr.pw/");