Android KitKat 中的 WebView 渲染问题

WebView Rendering Issue in Android KitKat

提问人:gnuanu 提问时间:12/19/2013 最后编辑:MartyIXgnuanu 更新时间:9/1/2016 访问量:38310

问:

我一直在开发一个具有 WebView 的应用程序,其中静态页面从资产中加载(也使用 JavaScript)。此 WebView 在 KitKat 中不起作用,它仍然是空白的。我知道渲染引擎(webkit 到 chromium)的变化发生在 kitkat 的 WebView 中,并尝试了迁移步骤,这在 Android 开发人员页面中给出。但这无济于事。

在logcat中,我收到一个从Chromium源抛出的错误。

W/AwContents﹕ nativeOnDraw failed; clearing to background color.

请提出解决方法。

安卓 webview android-4.4-kitkat

评论

0赞 JiTHiN 12/19/2013
请使硬件加速关闭。 Chromium WebView 不支持硬件加速画布渲染。
0赞 gnuanu 12/19/2013
尝试禁用WebView的硬件加速,但也没有用。
0赞 ksasq 1/5/2014
您能否分享有关您正在加载的内容的更多详细信息?您是否尝试过使用远程调试来检查加载到 WebView 中的内容?(developers.google.com/chrome-developer-tools/docs/...)
0赞 mikejonesguy 1/8/2014
我也看到了这一点。就我而言,我在“阅读选项”活动中有一个小的 Web 视图,它显示一些示例文本并允许用户调整字体大小、更改背景等。如果我的活动是从操作栏启动的,文本呈现良好(但我仍然在 logcat 中看到此错误)。但是,如果我从 PreferenceActivity 中启动,则它不会呈现文本。使用远程 webview 调试的检查显示一个没有内容的空页面 (<html><head></head><body></body></html>),即使这不是我通过 loadDataWithBaseURL 加载的内容。
0赞 markostamcar 8/27/2014
我刚刚找到了这个提交:src.chromium.org/viewvc/chrome/trunk/src/android_webview/java/...也许使用反射调用 mSettings.setEnableSupportedHardwareAcceleratedFeatures(false) 可以修复它。

答:

6赞 DataDino 12/21/2013 #1

我遇到了同样的问题,但我确实找到了解决方法。您所要做的就是为您的网页显式设置CSS背景。这样:

body {
  background: white;
}

事实证明,如果您没有为网页显式设置背景,WebView 将无法绘制所述背景,并且您最终会得到一个透明的 WebView。

45赞 georgiecasey 2/26/2014 #2

就我而言,在 Android 4.4 中,无论我设置什么,我都会得到一个黑色背景,并且我的 LogCat 中的此错误消息:nativeOnDraw 失败;清除为背景颜色。

从谷歌搜索来看,这似乎是因为 Chromium WebView 不支持硬件加速画布渲染。我将此行添加到 WebView 以关闭硬件加速画布,现在它可以工作了。

mWebview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

评论

0赞 Hannes Struß 7/24/2014
这也加快了我的初始化时间。我在 ViewPager 中有几个 Web 视图,当切换页面然后弹出到视图中时,它们通常显示为空白。使用软件渲染在这方面有很大帮助。
2赞 Ahmed Hegazy 10/22/2014
您不会在 webview 中播放 html5 视频,因为您确实通过设置LAYER_TYPE_SOFTWARE关闭了硬件加速画布。
0赞 Chris Fawcett 12/31/2014
我遇到了同样的问题,上述修复有效。但是,我们在 Kindle Fire 4.1.1 及更高版本上看到了类似的问题,在这种情况下,解决方法没有任何影响。我尝试过使用 AmazonWebView,但没有任何区别。我在亚马逊论坛上发帖,但没有得到任何回应。任何建议将不胜感激。
1赞 Chris Fawcett 1/29/2015
以防万一其他人遇到 Kindle Fire 4.1 及更高版本 WebView 中未显示的图像问题,显然上述修复程序 (setLayerType) 导致了问题。当我删除它时,图像会重新出现。但我仍然需要它用于常规 Android 设备上的 KitKat
0赞 Vivek Maskara 1/27/2018
我尝试禁用硬件加速,但可以清楚地看到 GPU 渲染时间增加。启用硬件加速后,我的渲染时间在大部分时间里为 <16 毫秒。禁用后,它不断>25-30ms。除了渲染时间增加之外,我无法验证这是否对用户也存在任何明显的性能问题。此解决方案是否存在与性能相关的权衡?对我来说,这个问题偶尔会发生。
4赞 Tore Rudberg 7/3/2014 #3

这似乎是一个 chromium webview 错误。

这是关于该问题的帖子: https://jira.appcelerator.org/browse/TIMOB-16479

显然,公认的答案并不是一个确定的解决方案。链接中提到了解决方法。

评论

0赞 gnuanu 7/24/2014
接受的答案是否是确定的解决方法并不重要,但它确实对我有用,并且仍然没有任何问题。
0赞 Tore Rudberg 8/19/2014
确定。我的评论只是为了帮助其他不起作用的用户。接受的答案并没有为我解决问题。
-2赞 Raj008 11/28/2014 #4
package com.example.testandroid;



public class MainActivity extends ActionBarActivity {

WebView webView=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);


    if (savedInstanceState != null)
    {
        ((WebView)findViewById(R.id.web_view)).restoreState(savedInstanceState);
    }
    else{

        webView=(WebView)findViewById(R.id.web_view);
        webView.loadUrl("http://www.google.co.in");
        webView.getSettings().getJavaScriptEnabled();
        webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

        webView.setWebViewClient(new WebViewClient()

        {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view,
                    String url) {
                // TODO Auto-generated method stub
                view.loadUrl(url);
                return true;
            }
        });
    }
}


protected void onSaveInstanceState(Bundle outState) {
    webView.saveState(outState);
}


@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    // Check if the key event was the Back button and if there's history
    if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
        webView.goBack();
        return true;
    }
    // If it wasn't the Back key or there's no web page history, bubble up to the default
    // system behavior (probably exit the activity)
    return super.onKeyDown(keyCode, event);
}

}

评论

2赞 TechSpellBound 3/10/2015
请添加一些解释!
0赞 asiop 9/1/2016 #5

硬件加速器的禁用会带来严重的性能损失,就我而言,我发现在 Kitkat 中,当我在已完成并随后重新启动的活动中重新实例化 webview 元素时,这种情况发生在我身上。 经过大量的反复试验,当我添加:

RelativeLayout layout = (RelativeLayout) findViewById(R.id.webViewContainer);
layout.removeAllViews();
webview.destroy();

就在结束活动之前,它似乎已经解决了问题。我还没有在许多设备上测试过它,但如果这个解决方案是正确的,那么它比禁用 KitKat 的硬件加速要好得多。