Issue
Currently I am developing a mobile app which makes use auf the UNO platform. For showing a 3D model I make use of the WebView control and some ThreeJS JavaScript code. This works quite well with UWP and also with WASM. (The Workaround for WebView in WASM build can also be found here on StackOverflow.) However, the Android build makes me getting a headache: The HTML page loads, the debug output shows me that the WebGL script parts are being executed, but the user interface does not show anything.
I already made sure that (in my opinion) the correct WebView control is used. In addition, I tested with an alternative WebView from "Chrome" which I downloaded from the "Play Store" (Version 74.x.x.x). The WebView's HTTP user agent is correct, so the WebView is used according to the Android system's developer settings. Hardware accelaration is set to "TRUE" in both, the activity and in the AndroidManifest file.
I also made a very simple test with an "Android-XAML-App" which is working out of the box. The cube is shown almost instantly.
MainView.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>
This is an example of the UNO main page which does not work. The page is loading but the 3D cube is not shown.
MainPage.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>
I compared the manifest files but so far I did not come to a conclusion I could investigate any further. I would expect that UNO is using the native Android WebView control, but maybe there is missing some setting or it isn't even the same control?
Solution
Indeed this is due to Uno's WebView disabling hardware acceleration. Apart from this, Uno and Xamarin.Forms are similarly using Android.WebKit.WebView under the hood.
The hardware acceleration can be reenabled in Uno easily using an attached property:
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
}
This can then be used in XAML like so:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<WebView Source="https://threejs.org/examples/?q=cube#webgl_geometry_cube" local:WebViewHardware.IsEnabled="True"/>
</Grid>
Answered By - David Oliver
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.