c# - WebView 中的 WebGL 在 UNO 构建中不起作用,但在 Xamarin 构建中起作用
问题描述
目前我正在开发一个使用 auf UNO 平台的移动应用程序。为了显示 3D 模型,我使用了 WebView 控件和一些 ThreeJS JavaScript 代码。这对 UWP 和 WASM 都非常有效。(WASM 构建中 WebView 的解决方法也可以在StackOverflow 上找到。)但是,Android 构建让我头疼:HTML 页面加载,调试输出显示 WebGL 脚本部分正在执行,但用户界面不显示任何东西。
我已经确保(在我看来)使用了正确的 WebView 控件。此外,我使用从“Play Store”(版本 74.xxx)下载的“Chrome”替代 WebView 进行了测试。WebView 的 HTTP 用户代理是正确的,所以 WebView 是根据 Android 系统的开发者设置使用的。在活动和 AndroidManifest 文件中,硬件加速都设置为“TRUE”。
我还用开箱即用的“Android-XAML-App”做了一个非常简单的测试。立方体几乎立即显示出来。
主视图.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:WebViewTestAndroid"
x:Class="WebViewTestAndroid.MainPage">
<Grid>
<WebView Source="https://threejs.org/examples/?q=cube#webgl_geometry_cube" />
</Grid>
</ContentPage>
这是 UNO 主页不起作用的示例。页面正在加载,但未显示 3D 立方体。
主页.xaml
<Page
x:Class="UnoWebViewTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UnoWebViewTest"
xmlns:ios="http://uno.ui/ios"
xmlns:android="http://uno.ui/android"
xmlns:xamarin="http://uno.ui/xamarin"
xmlns:wasm="http://uno.ui/wasm"
mc:Ignorable="d ios android xamarin wasm"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<android:WebView Source="https://threejs.org/examples/?q=cube#webgl_geometry_cube" />
</Grid>
</Page>
我比较了清单文件,但到目前为止我还没有得出可以进一步调查的结论。我希望 UNO 使用的是原生 Android WebView 控件,但可能缺少一些设置,或者它甚至不是同一个控件?
解决方案
事实上,这是由于 Uno 的 WebView 禁用了硬件加速。除此之外,Uno 和 Xamarin.Forms 在后台同样使用 Android.WebKit.WebView。
可以使用附加属性在 Uno 中轻松重新启用硬件加速:
public static class WebViewHardware
{
public static bool GetIsEnabled(WebView obj)
{
return (bool)obj.GetValue(IsEnabledProperty);
}
public static void SetIsEnabled(WebView obj, bool value)
{
obj.SetValue(IsEnabledProperty, value);
}
// Using a DependencyProperty as the backing store for IsEnabled. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsEnabledProperty =
DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(WebViewHardware), new PropertyMetadata(false, OnIsEnabledChanged));
private static void OnIsEnabledChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
var webView = (WebView)dependencyObject;
var isEnabled = (bool)args.NewValue;
#if __ANDROID__
webView.Loaded += OnLoaded;
void OnLoaded(object sender, RoutedEventArgs e)
{
webView.Loaded -= OnLoaded;
var layerType = isEnabled ? Android.Views.LayerType.Hardware : Android.Views.LayerType.Software;
webView.SetLayerType(layerType, null);
}
#endif
}
然后可以像这样在 XAML 中使用它:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<WebView Source="https://threejs.org/examples/?q=cube#webgl_geometry_cube" local:WebViewHardware.IsEnabled="True"/>
</Grid>
推荐阅读
- php - 如何在 Laravel 中获取推送器实例?
- c - C 字段的类型不完整
- c - C:声明没有大小的多维数组?
- c# - 如果我按 Enter 键,如何在多行文本框中将最后一行文本串起来
- python - 用 cv2.imwrite 保存 BGR 图像
- php - CLI 和 Apache() 上 exec() 的区别
- angular - 如何正确使用 PrimeNG 的 Dropdown
- numpy - 3D 绘图未显示
- python - 20 个新闻组数据集包含大约 18000 个新闻组帖子,而 sklearn 只加载了大约一半的数据集,这是为什么呢?
- javascript - 如何根据查询更新 Firestore 上的文档