【问题标题】:WebView "flashing" with white background if hardware acceleration is enabled (Android 3.0+)如果启用了硬件加速(Android 3.0+),WebView “闪烁”为白色背景
【发布时间】:2012-03-17 13:59:38
【问题描述】:

我遇到了 WebView (Android 3.0+) 的问题,WebView 在显示我的黑色背景之前总是显示白色背景(“闪烁”)。这是我的简单测试代码:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    WebView webView = new WebView(this);
    webView.setBackgroundColor(Color.BLACK);
    setContentView(webView);
    loadWebView(webView);
    webView.loadDataWithBaseURL("localhost://", "<html><head>" +
            "<style>body {background-color: #000}img{max-width:100%}</style></head>" +
            "<body>" +
            "<img src=\"http://developer.android.com/images/practices/actionbar-phone-splitaction.png\" />" +
            "</body></html>", 
            "text/html", "UTF-8", null);
}

我尝试了很多解决方案来解决这个问题,但并不幸运。

PS:关闭硬件加速不会出现此问题。有人遇到同样的问题并解决了吗?

谢谢。

【问题讨论】:

标签: android webview android-3.0-honeycomb android-4.0-ice-cream-sandwich hardware-acceleration


【解决方案1】:

我已为应用程序启用硬件加速并为活动禁用它。另外,如上所述,我将背景设置为null。它现在对我有用。

另一种方法(未测试):将图层类型设置为软件渲染并将背景设置为Color.TRANSPARENT(或0):webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

格雷茨·托尔斯滕

【讨论】:

  • LAYER_TYPE_SOFTWARE 未声明抛出异常
  • webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);是 API 11
  • 只是一个预热,将图层类型设置为 null 将禁用硬件加速,因此在 WebView 中播放视频!我花了几个小时才弄清楚为什么视频没有播放。
【解决方案2】:

这显然是 Android 版本 >3 的可怕“功能”。甚至官方应用谷歌阅读器也包含这个白色闪光。解决方案是禁用 Activity 的硬件加速,您需要使用快速绘图 Web 视图。

【讨论】:

    【解决方案3】:

    网页视图也有类似的问题。 我曾在 Ice Cream Sandwich 工作,并将 minSdk = 13 放入 Android Manifest 对我有用。 尝试对此进行试验。我猜SDK中存在一些错误。

    【讨论】:

      【解决方案4】:

      我发现最有效的解决方法是first mentioned here,是在布局膨胀后设置透明背景色:

      webView.setBackgroundColor(Color.argb(1, 0, 0, 0));
      

      是的,这完全是 hack,但这是我发现的唯一一个在不禁用硬件加速的情况下运行良好的解决方案。

      请注意,这不能通过在 XML 中设置背景来实现。

      这已在 Jellybean 中得到解决,尽管一些用户报告在 KitKat 中看到了此问题。检查您是否没有禁用硬件加速,如果问题确实消失了,您可能希望将该代码包装在条件语句中以仅针对旧设备:

      if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
          webView.setBackgroundColor(Color.argb(1, 0, 0, 0));
      }
      

      【讨论】:

      • 我在调用 webView.setBackgroundColor(Color.TRANSPARENT);但这没有用。但是,使用 Color.argb(1,0,0,0) 时不再闪烁
      • @PaulLammertsma 我在 kitkat 中看到了这个问题,所以包装代码并检查到 jellybean 是错误的......
      • 您好。此修复程序在 4.4.4(Nexus 5)中对我有用。在 4.4.4 中,我也在 web 视图中遇到了这个闪烁问题。
      • 我可以确认在 Lollypop 上使用标准 WebView 仍然存在问题(我正在使用 Unity3D 的 UniWebView 插件),但这确实解决了问题。
      • 7 年后,我仍然在 WebView 中遇到同样的问题,其中使用 setLayerType(HARDWARE,...) 和 kotlin 会导致白色闪烁。不幸的是,到目前为止,这个线程中的解决方案都没有奏效。
      【解决方案5】:

      在 Android 4.4.4 上遇到此问题,并且此处的其他解决方案均无效。反正我在玩onPageFinished(),所以不妨尝试一下应该是防弹的东西:

      我把它放在承载 WebView 的片段的 onCreateView() 中:

          webView = (WebView) v.findViewById(R.id.webView);
          webView.setVisibility(View.INVISIBLE);
          webView.setBackgroundColor(Color.argb(1, 0, 0, 0));         
      
          webView.setWebViewClient( new WebViewClient(){
              @Override
              public void onPageFinished(WebView view, String url) {
                  view.setVisibility(View.VISIBLE);
                  super.onPageFinished(view, url);
              }
          });
      

      这个想法只是在第一页加载之前隐藏 WebView。但是,它仍然给了我一点点白光,直到我还添加了 Paul Lammertsma 提供的解决方案,webView.setBackgroundColor(Color.argb(1, 0, 0, 0));

      【讨论】:

      • 谢谢!不过我有一个问题:webview 内容现在是不可见的(显然),直到它完全完成加载。如果我的内容有很多图像需要一些时间来加载,那么在所有图像加载时整个内容都是不可见的。我希望在加载图像时立即显示内容,因为 webview 将很好地显示其余内容并在完成后添加图像。但这不适用于这种方法,因为我们隐藏了它。有什么想法可以解决这个问题吗?我尝试在 onPageStarted 中将其变为可见,但这会带回白色闪光:(
      • 不确定如何做到这一点,因为我从资产文件夹加载本地 HTML 文件,所以没有这个问题。也许您可以尝试某种重定向? (即加载一个页面,然后重定向到另一个页面)
      【解决方案6】:

      就这样吧:

      WebView web=(WebView)findViewById(R.id.web);
      web.setBackgroundColor(0xff000000);
      

      【讨论】:

        【解决方案7】:

        现在是 2021 年,我仍然为此苦苦挣扎,并想分享我的经验。我发现的解决方案都没有奏效。我不能关闭 webview 的硬件加速,因为这意味着太多的性能损失。在尝试了一堆解决方案之后,我意识到不可能将 webview 的可见性从 View.INVISIBLE 更改为 View.VISIBLE 而不会导致闪烁/闪烁/闪烁。所以,我让 webview 可见。但是,我在布局文件中将 webview 的半透明设置为透明。在加载 url 时,webview 是透明的。加载页面后,我将 webview 设置为不透明以在屏幕上显示 webview。由于 webview 可见性没有变化,因此不存在闪烁/闪烁/闪烁问题。

        布局文件:

            <WebView
                android:id="@+id/WebView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_centerHorizontal="true"
                android:alpha="0.0"
                android:background="@android:color/transparent"
            />
        

        MainActivity.kt:

            mWebView.webViewClient = object : WebViewClient() {
                override fun onPageFinished(view: WebView?, url: String?) {
                    super.onPageFinished(view, url)
        
                    // code for other stuff
        
                    // Change the webview translucency from transparent to opaque.
                    // This is a workaround of the Android bug of webview blinking when hardware acceleration is turned on
                    // Basically, we cannot change the webview visibility to show and hide the webview.
                    // Doing so would cause flickering/blinking with hardware acceleration).
                    // Instead, the webview is visible the entire time.
                    // We set the webview to be transparent while loading a page and then change the webview
                    // to opaque once the page is loaded to make the webview visible to the user.
                    if (mWebView.alpha < 1.0F) {
                        mWebView.alpha = 1.0F
                    }
        
                    // more code for other stuff
                }
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-24
          • 1970-01-01
          • 1970-01-01
          • 2017-07-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多