【问题标题】:Android WebView with layer_type_software not showing HTML5 canvas content带有 layer_type_software 的 Android WebView 不显示 HTML5 画布内容
【发布时间】:2019-08-12 16:59:36
【问题描述】:

自上次更新 Android WebView 以来,当通过将 WebView 的图层类型设置为 View.LAYER_TYPE_SOFTWARE 禁用硬件加速时,无法正确显示带有 HTML5 画布的网页。这个问题有解决办法吗?

当我省略以下 Java 代码行时: webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); 然后内容显示正确。

Java 代码:

WebView webView = findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
webView.loadUrl("file:///android_asset/Gradient.html");

html文件test.html:

<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="200" height="100" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// Create gradient
var grd = ctx.createLinearGradient(0,0,200,0);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
// Fill with gradient
ctx.fillStyle = grd;
ctx.fillRect(10,10,150,80);
</script>
</body>
</html>

预期结果: 黑色边框中的红色线性渐变 https://heiri-web.ch/Gradient.png

实际结果: 空的黑色边框 https://heiri-web.ch/Empty.png

【问题讨论】:

    标签: android android-webview


    【解决方案1】:

    在向 Google 提交了错误报告 https://issuetracker.google.com/issues/139276381 后,我收到了该错误不会被修复的回复,因为 LAYER_TYPE_SOFTWARE 已过时。因为我需要LAYER_TYPE_SOFTWARE 使用WebView.getDrawingCache() 获得完整的屏幕截图(包括HTML5 画布内容),所以我要求另一种方法。

    在 WebView 开发团队成员 Bo Liu 的建议下,我设法在不使用 LAYER_TYPE_SOFTWARE 的情况下获得了 WebView 的完整截图: 创建一个 ImageReader,使用ImageReader.getSurface() 获取一个 Surface,在 Surface 上创建一个 VirtualDisplay,使用 VirtualDisplay.getDisplay() 获取一个 Display,在其布局中创建一个带有 WebView 的 Presentation,使用 Presentation.show(),使用 @987654329 @ 读取 WebView 内容的渲染图像。

    【讨论】:

      【解决方案2】:

      我发现解决 Android webview 中 HTML5 画布问题的关键在于 AndroidManifest.xml。我必须做什么?我保留了使用混合(自定义)webview 的策略,因为当我在 Xamarin Forms 中为 iOS 和 Android 开发时,我需要在两个平台上使用相同的解决方案。在 Android 上我做到了:

      // Java (or similar [laughs])
      // Enable hardware acceleration using code (>= level 19)
      if (Build.VERSION.SDK_INT >= 19) {
          yourWebviewObj.setLayerType(View.LAYER_TYPE_HARDWARE, null);
      } else {
          yourWebviewObj.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
      }
      
      yourSettingsObj.setRenderPriority(WebSettings.RenderPriority.HIGH);
      yourSettingsObj.setCacheMode(WebSettings.LOAD_NO_CACHE);
      
      // Xamarin for Android
      // Enable hardware acceleration using code (>= level 19)
      if (Build.VERSION.SdkInt >= 19)
      {
          yourWebviewObj.SetLayerType (LayerType.Hardware, null);
      }
      else
      {
          yourWebviewObj.SetLayerType (LayerType.Software, null);
      }
      
      yourWebviewObj.Settings.SetRenderPriority(WebSettings.RenderPriority.High);
      yourWebviewObj.Settings.CacheMode = CacheModes.NoCache;
      

      最后,在 AndroidManifest.xml 中找到android:handwareAccelerated="false",您可以将值从false 更改为true。本技巧(另外)适用于 Java 世界和 Xamarin。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-22
        • 2018-09-14
        • 2013-10-10
        • 1970-01-01
        • 1970-01-01
        • 2023-03-18
        相关资源
        最近更新 更多