From d48b61b5d0bc2aaf1a9e19f598837804ffaecaee Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 6 Mar 2022 19:13:31 +0000 Subject: [PATCH 01/10] singleview lifetime for android. --- samples/ControlCatalog.Android/MainActivity.cs | 7 ------- samples/ControlCatalog.Android/SplashActivity.cs | 3 +-- src/Android/Avalonia.Android/AndroidPlatform.cs | 15 ++++++++++++++- src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs | 16 +++------------- src/iOS/Avalonia.iOS/Platform.cs | 2 ++ src/iOS/Avalonia.iOS/SingleViewLifetime.cs | 15 ++++++++++++--- 6 files changed, 32 insertions(+), 26 deletions(-) diff --git a/samples/ControlCatalog.Android/MainActivity.cs b/samples/ControlCatalog.Android/MainActivity.cs index b02083c39d..cb3565bcac 100644 --- a/samples/ControlCatalog.Android/MainActivity.cs +++ b/samples/ControlCatalog.Android/MainActivity.cs @@ -1,5 +1,4 @@ using Android.App; -using Android.OS; using Android.Content.PM; using Avalonia.Android; @@ -8,11 +7,5 @@ namespace ControlCatalog.Android [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)] public class MainActivity : AvaloniaActivity { - protected override void OnCreate(Bundle? savedInstanceState) - { - base.OnCreate(savedInstanceState); - - Content = new MainView(); - } } } diff --git a/samples/ControlCatalog.Android/SplashActivity.cs b/samples/ControlCatalog.Android/SplashActivity.cs index 9729713833..6d5fd0714c 100644 --- a/samples/ControlCatalog.Android/SplashActivity.cs +++ b/samples/ControlCatalog.Android/SplashActivity.cs @@ -22,8 +22,7 @@ namespace ControlCatalog.Android if (Avalonia.Application.Current == null) { AppBuilder.Configure() - .UseAndroid() - .SetupWithoutStarting(); + .UseAndroid(); } StartActivity(new Intent(Application.Context, typeof(MainActivity))); diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index 308be1325c..ed1b43cf3e 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -4,6 +4,7 @@ using Avalonia.Android; using Avalonia.Android.Platform; using Avalonia.Android.Platform.Input; using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.Platform; using Avalonia.Input; using Avalonia.Input.Platform; @@ -14,6 +15,17 @@ using Avalonia.Skia; namespace Avalonia { + public class SingleViewLifetime : ISingleViewApplicationLifetime + { + public AvaloniaView View; + + public Control MainView + { + get => (Control)View.Content; + set => View.Content = value; + } + } + public static class AndroidApplicationExtensions { public static T UseAndroid(this T builder) where T : AppBuilderBase, new() @@ -21,7 +33,8 @@ namespace Avalonia var options = AvaloniaLocator.Current.GetService() ?? new AndroidPlatformOptions(); return builder .UseWindowingSubsystem(() => AndroidPlatform.Initialize(options), "Android") - .UseSkia(); + .UseSkia() + .SetupWithLifetime(new SingleViewLifetime()); } } } diff --git a/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs b/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs index 65a6743f9d..55afe72a25 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs @@ -1,5 +1,3 @@ -using Avalonia.Controls; -using Avalonia.Controls.ApplicationLifetimes; using Foundation; using UIKit; @@ -18,7 +16,9 @@ namespace Avalonia.iOS { var builder = AppBuilder.Configure(); CustomizeAppBuilder(builder); - var lifetime = new Lifetime(); + + var lifetime = new SingleViewLifetime(); + builder.AfterSetup(_ => { Window = new UIWindow(); @@ -35,15 +35,5 @@ namespace Avalonia.iOS Window.Hidden = false; return true; } - - class Lifetime : ISingleViewApplicationLifetime - { - public AvaloniaView View; - public Control MainView - { - get => View.Content; - set => View.Content = value; - } - } } } diff --git a/src/iOS/Avalonia.iOS/Platform.cs b/src/iOS/Avalonia.iOS/Platform.cs index 57a86cbfd8..f8815e9030 100644 --- a/src/iOS/Avalonia.iOS/Platform.cs +++ b/src/iOS/Avalonia.iOS/Platform.cs @@ -45,6 +45,7 @@ namespace Avalonia.iOS Timer ??= new DisplayLinkTimer(); var keyboard = new KeyboardDevice(); var softKeyboard = new SoftKeyboardHelper(); + AvaloniaLocator.CurrentMutable .Bind().ToConstant(GlFeature) .Bind().ToConstant(new CursorFactoryStub()) @@ -57,6 +58,7 @@ namespace Avalonia.iOS .Bind().ToConstant(Timer) .Bind().ToConstant(new PlatformThreadingInterface()) .Bind().ToConstant(keyboard); + keyboard.PropertyChanged += (_, changed) => { if (changed.PropertyName == nameof(KeyboardDevice.FocusedElement)) diff --git a/src/iOS/Avalonia.iOS/SingleViewLifetime.cs b/src/iOS/Avalonia.iOS/SingleViewLifetime.cs index 914f0ba548..16cbcaace4 100644 --- a/src/iOS/Avalonia.iOS/SingleViewLifetime.cs +++ b/src/iOS/Avalonia.iOS/SingleViewLifetime.cs @@ -1,7 +1,16 @@ +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; + namespace Avalonia.iOS { - public class SingleViewLifetime + public class SingleViewLifetime : ISingleViewApplicationLifetime { - + public AvaloniaView View; + + public Control MainView + { + get => View.Content; + set => View.Content = value; + } } -} \ No newline at end of file +} From 61744546a87c4a418e38fd958450793bdf2a0926 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 6 Mar 2022 19:34:42 +0000 Subject: [PATCH 02/10] make singleview lifetimes private classes. --- .../Avalonia.Android/AndroidPlatform.cs | 21 ++++++++++--------- src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs | 11 ++++++++++ src/iOS/Avalonia.iOS/SingleViewLifetime.cs | 16 -------------- 3 files changed, 22 insertions(+), 26 deletions(-) delete mode 100644 src/iOS/Avalonia.iOS/SingleViewLifetime.cs diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index ed1b43cf3e..baa13419f1 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -1,5 +1,6 @@ using System; - +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Android; using Avalonia.Android.Platform; using Avalonia.Android.Platform.Input; @@ -15,19 +16,19 @@ using Avalonia.Skia; namespace Avalonia { - public class SingleViewLifetime : ISingleViewApplicationLifetime + public static class AndroidApplicationExtensions { - public AvaloniaView View; - - public Control MainView + class SingleViewLifetime : ISingleViewApplicationLifetime { - get => (Control)View.Content; - set => View.Content = value; + public AvaloniaView View; + + public Control MainView + { + get => (Control)View.Content; + set => View.Content = value; + } } - } - public static class AndroidApplicationExtensions - { public static T UseAndroid(this T builder) where T : AppBuilderBase, new() { var options = AvaloniaLocator.Current.GetService() ?? new AndroidPlatformOptions(); diff --git a/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs b/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs index 55afe72a25..6f1cf8f8f9 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs @@ -6,6 +6,17 @@ namespace Avalonia.iOS public class AvaloniaAppDelegate : UIResponder, IUIApplicationDelegate where TApp : Application, new() { + class SingleViewLifetime : ISingleViewApplicationLifetime + { + public AvaloniaView View; + + public Control MainView + { + get => View.Content; + set => View.Content = value; + } + } + protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder.UseiOS(); [Export("window")] diff --git a/src/iOS/Avalonia.iOS/SingleViewLifetime.cs b/src/iOS/Avalonia.iOS/SingleViewLifetime.cs deleted file mode 100644 index 16cbcaace4..0000000000 --- a/src/iOS/Avalonia.iOS/SingleViewLifetime.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Controls.ApplicationLifetimes; - -namespace Avalonia.iOS -{ - public class SingleViewLifetime : ISingleViewApplicationLifetime - { - public AvaloniaView View; - - public Control MainView - { - get => View.Content; - set => View.Content = value; - } - } -} From d7d6f8decb20b00b0ae19d156af0bb96c3487603 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 6 Mar 2022 19:57:51 +0000 Subject: [PATCH 03/10] Locator ftw --- .../Avalonia.Android/AndroidPlatform.cs | 17 ++++---------- .../Avalonia.Android/AvaloniaActivity.cs | 23 ++++++++++++++++--- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index baa13419f1..0322e38d17 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -18,24 +18,17 @@ namespace Avalonia { public static class AndroidApplicationExtensions { - class SingleViewLifetime : ISingleViewApplicationLifetime - { - public AvaloniaView View; - public Control MainView - { - get => (Control)View.Content; - set => View.Content = value; - } - } - - public static T UseAndroid(this T builder) where T : AppBuilderBase, new() + public static T UseAndroid(this T builder, AvaloniaView view) where T : AppBuilderBase, new() { var options = AvaloniaLocator.Current.GetService() ?? new AndroidPlatformOptions(); + + var lifetime = AvaloniaLocator.Current.GetService(); + return builder .UseWindowingSubsystem(() => AndroidPlatform.Initialize(options), "Android") .UseSkia() - .SetupWithLifetime(new SingleViewLifetime()); + .SetupWithLifetime(lifetime); } } } diff --git a/src/Android/Avalonia.Android/AvaloniaActivity.cs b/src/Android/Avalonia.Android/AvaloniaActivity.cs index fbadc257e2..ead1307ce6 100644 --- a/src/Android/Avalonia.Android/AvaloniaActivity.cs +++ b/src/Android/Avalonia.Android/AvaloniaActivity.cs @@ -1,15 +1,30 @@ -using Android.App; using Android.OS; -using Android.Views; -using Android.Content.PM; using AndroidX.AppCompat.App; using Android.Content.Res; using AndroidX.Lifecycle; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Controls; namespace Avalonia.Android { public abstract class AvaloniaActivity : AppCompatActivity { + class SingleViewLifetime : ISingleViewApplicationLifetime + { + public SingleViewLifetime(AvaloniaView view) + { + View = view; + } + + public AvaloniaView View; + + public Control MainView + { + get => (Control)View.Content; + set => View.Content = value; + } + } + internal AvaloniaView View; internal AvaloniaViewModel _viewModel; protected override void OnCreate(Bundle savedInstanceState) @@ -24,6 +39,8 @@ namespace Avalonia.Android View.Content = _viewModel.Content; } + AvaloniaLocator.CurrentMutable.Bind().ToConstant(new SingleViewLifetime(View)); + base.OnCreate(savedInstanceState); } public object Content From 824afa2e33e3d01ad2b26a5d893ea50e75338560 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 6 Mar 2022 19:58:56 +0000 Subject: [PATCH 04/10] fix build --- src/Android/Avalonia.Android/AndroidPlatform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index 0322e38d17..7cc771ce41 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -19,7 +19,7 @@ namespace Avalonia public static class AndroidApplicationExtensions { - public static T UseAndroid(this T builder, AvaloniaView view) where T : AppBuilderBase, new() + public static T UseAndroid(this T builder) where T : AppBuilderBase, new() { var options = AvaloniaLocator.Current.GetService() ?? new AndroidPlatformOptions(); From 8f3e9e2cc07e1769245c60c1f96ed212ef1609e0 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 6 Mar 2022 20:17:27 +0000 Subject: [PATCH 05/10] fix build. --- src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs b/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs index 6f1cf8f8f9..f976b2feb4 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs @@ -1,4 +1,7 @@ using Foundation; +using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; + using UIKit; namespace Avalonia.iOS From 8f6b9e1b230d7b5a8928027efa8331c912d00956 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Sun, 6 Mar 2022 21:11:32 +0000 Subject: [PATCH 06/10] re-order initialisation and lifetime config. --- src/Android/Avalonia.Android/AndroidPlatform.cs | 3 +++ src/Android/Avalonia.Android/AvaloniaActivity.cs | 13 ++++--------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index 7cc771ce41..8cb9f193c2 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -13,6 +13,7 @@ using Avalonia.OpenGL.Egl; using Avalonia.Platform; using Avalonia.Rendering; using Avalonia.Skia; +using static Avalonia.Android.AvaloniaActivity; namespace Avalonia { @@ -23,6 +24,8 @@ namespace Avalonia { var options = AvaloniaLocator.Current.GetService() ?? new AndroidPlatformOptions(); + AvaloniaLocator.CurrentMutable.Bind().ToConstant(new SingleViewLifetime()); + var lifetime = AvaloniaLocator.Current.GetService(); return builder diff --git a/src/Android/Avalonia.Android/AvaloniaActivity.cs b/src/Android/Avalonia.Android/AvaloniaActivity.cs index ead1307ce6..a8c501e8b1 100644 --- a/src/Android/Avalonia.Android/AvaloniaActivity.cs +++ b/src/Android/Avalonia.Android/AvaloniaActivity.cs @@ -9,13 +9,8 @@ namespace Avalonia.Android { public abstract class AvaloniaActivity : AppCompatActivity { - class SingleViewLifetime : ISingleViewApplicationLifetime + internal class SingleViewLifetime : ISingleViewApplicationLifetime { - public SingleViewLifetime(AvaloniaView view) - { - View = view; - } - public AvaloniaView View; public Control MainView @@ -34,13 +29,13 @@ namespace Avalonia.Android _viewModel = new ViewModelProvider(this).Get(Java.Lang.Class.FromType(typeof(AvaloniaViewModel))) as AvaloniaViewModel; + var lifetime = AvaloniaLocator.Current.GetService() as SingleViewLifetime; + lifetime.View = View; + if (_viewModel.Content != null) { View.Content = _viewModel.Content; } - - AvaloniaLocator.CurrentMutable.Bind().ToConstant(new SingleViewLifetime(View)); - base.OnCreate(savedInstanceState); } public object Content From 52135b3a07bb9fdeb973754eb63967969e75f71e Mon Sep 17 00:00:00 2001 From: Benedikt Stebner Date: Mon, 7 Mar 2022 10:32:01 +0100 Subject: [PATCH 07/10] Fix compiled method to command binding --- .../CompilerExtensions/XamlIlBindingPathHelper.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs index db4cee32b0..c8de8f00f6 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/XamlIlBindingPathHelper.cs @@ -72,10 +72,19 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions private static XamlIlBindingPathNode TransformForTargetTyping(XamlIlBindingPathNode transformed, AstTransformationContext context) { - if (context.ParentNodes().OfType().FirstOrDefault().Property.Getter.ReturnType == context.GetAvaloniaTypes().ICommand - && transformed.Elements[transformed.Elements.Count - 1] is XamlIlClrMethodPathElementNode method) + var parentNode = context.ParentNodes().OfType().FirstOrDefault(); + + if (parentNode == null) + { + return transformed; + } + + var lastElement = + transformed.Elements[transformed.Elements.Count - 1]; + + if (parentNode.Property?.Getter?.ReturnType == context.GetAvaloniaTypes().ICommand && lastElement is XamlIlClrMethodPathElementNode methodPathElement) { - IXamlMethod executeMethod = method.Method; + IXamlMethod executeMethod = methodPathElement.Method; IXamlMethod canExecuteMethod = executeMethod.DeclaringType.FindMethod(new FindMethodMethodSignature($"Can{executeMethod.Name}", context.Configuration.WellKnownTypes.Boolean, context.Configuration.WellKnownTypes.Object)); List dependsOnProperties = new(); if (canExecuteMethod is not null) From 77f339d225efe42ae8e3ad48743d6ee62c9238e2 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 7 Mar 2022 10:00:27 +0000 Subject: [PATCH 08/10] refactor android activity to allow appbuilder and singleviewlifetime. --- .../ControlCatalog.Android/MainActivity.cs | 7 +++- .../ControlCatalog.Android/SplashActivity.cs | 9 ----- .../Avalonia.Android/AndroidPlatform.cs | 6 ---- .../Avalonia.Android/AvaloniaActivity.cs | 35 +++++++++++++------ 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/samples/ControlCatalog.Android/MainActivity.cs b/samples/ControlCatalog.Android/MainActivity.cs index cb3565bcac..44290d9816 100644 --- a/samples/ControlCatalog.Android/MainActivity.cs +++ b/samples/ControlCatalog.Android/MainActivity.cs @@ -1,11 +1,16 @@ using Android.App; using Android.Content.PM; +using Avalonia; using Avalonia.Android; namespace ControlCatalog.Android { [Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)] - public class MainActivity : AvaloniaActivity + public class MainActivity : AvaloniaActivity { + protected override AppBuilder CustomizeAppBuilder(AppBuilder builder) + { + return base.CustomizeAppBuilder(builder); + } } } diff --git a/samples/ControlCatalog.Android/SplashActivity.cs b/samples/ControlCatalog.Android/SplashActivity.cs index 6d5fd0714c..dc292fd37b 100644 --- a/samples/ControlCatalog.Android/SplashActivity.cs +++ b/samples/ControlCatalog.Android/SplashActivity.cs @@ -1,9 +1,6 @@ using Android.App; using Android.Content; using Android.OS; -using Application = Android.App.Application; - -using Avalonia; namespace ControlCatalog.Android { @@ -19,12 +16,6 @@ namespace ControlCatalog.Android { base.OnResume(); - if (Avalonia.Application.Current == null) - { - AppBuilder.Configure() - .UseAndroid(); - } - StartActivity(new Intent(Application.Context, typeof(MainActivity))); } } diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index 8cb9f193c2..c19fb021e9 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -4,8 +4,6 @@ using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Android; using Avalonia.Android.Platform; using Avalonia.Android.Platform.Input; -using Avalonia.Controls; -using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.Platform; using Avalonia.Input; using Avalonia.Input.Platform; @@ -13,18 +11,14 @@ using Avalonia.OpenGL.Egl; using Avalonia.Platform; using Avalonia.Rendering; using Avalonia.Skia; -using static Avalonia.Android.AvaloniaActivity; namespace Avalonia { public static class AndroidApplicationExtensions { - public static T UseAndroid(this T builder) where T : AppBuilderBase, new() { var options = AvaloniaLocator.Current.GetService() ?? new AndroidPlatformOptions(); - - AvaloniaLocator.CurrentMutable.Bind().ToConstant(new SingleViewLifetime()); var lifetime = AvaloniaLocator.Current.GetService(); diff --git a/src/Android/Avalonia.Android/AvaloniaActivity.cs b/src/Android/Avalonia.Android/AvaloniaActivity.cs index a8c501e8b1..7927a13c44 100644 --- a/src/Android/Avalonia.Android/AvaloniaActivity.cs +++ b/src/Android/Avalonia.Android/AvaloniaActivity.cs @@ -7,11 +7,11 @@ using Avalonia.Controls; namespace Avalonia.Android { - public abstract class AvaloniaActivity : AppCompatActivity + public abstract class AvaloniaActivity : AppCompatActivity where TApp : Application, new() { internal class SingleViewLifetime : ISingleViewApplicationLifetime { - public AvaloniaView View; + public AvaloniaView View { get; internal set; } public Control MainView { @@ -22,20 +22,33 @@ namespace Avalonia.Android internal AvaloniaView View; internal AvaloniaViewModel _viewModel; + + protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder.UseAndroid(); + protected override void OnCreate(Bundle savedInstanceState) { - View = new AvaloniaView(this); - SetContentView(View); + var builder = AppBuilder.Configure(); + + CustomizeAppBuilder(builder); - _viewModel = new ViewModelProvider(this).Get(Java.Lang.Class.FromType(typeof(AvaloniaViewModel))) as AvaloniaViewModel; + var lifetime = new SingleViewLifetime(); - var lifetime = AvaloniaLocator.Current.GetService() as SingleViewLifetime; - lifetime.View = View; - - if (_viewModel.Content != null) + builder.AfterSetup(x => { - View.Content = _viewModel.Content; - } + View = new AvaloniaView(this); + SetContentView(View); + + _viewModel = new ViewModelProvider(this).Get(Java.Lang.Class.FromType(typeof(AvaloniaViewModel))) as AvaloniaViewModel; + lifetime.View = View; + + if (_viewModel.Content != null) + { + View.Content = _viewModel.Content; + } + }); + + builder.SetupWithLifetime(lifetime); + base.OnCreate(savedInstanceState); } public object Content From 91980bea549bc9818aeeeb13ad36d69e6b3f8691 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 7 Mar 2022 11:24:09 +0000 Subject: [PATCH 09/10] fix initialisation order. --- src/Android/Avalonia.Android/AvaloniaActivity.cs | 10 ++++++---- src/Android/Avalonia.Android/AvaloniaView.cs | 7 ++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Android/Avalonia.Android/AvaloniaActivity.cs b/src/Android/Avalonia.Android/AvaloniaActivity.cs index 7927a13c44..f5d620a97a 100644 --- a/src/Android/Avalonia.Android/AvaloniaActivity.cs +++ b/src/Android/Avalonia.Android/AvaloniaActivity.cs @@ -31,20 +31,22 @@ namespace Avalonia.Android CustomizeAppBuilder(builder); + View = new AvaloniaView(this); + SetContentView(View); + var lifetime = new SingleViewLifetime(); + lifetime.View = View; builder.AfterSetup(x => { - View = new AvaloniaView(this); - SetContentView(View); - _viewModel = new ViewModelProvider(this).Get(Java.Lang.Class.FromType(typeof(AvaloniaViewModel))) as AvaloniaViewModel; - lifetime.View = View; if (_viewModel.Content != null) { View.Content = _viewModel.Content; } + + View.Prepare(); }); builder.SetupWithLifetime(lifetime); diff --git a/src/Android/Avalonia.Android/AvaloniaView.cs b/src/Android/Avalonia.Android/AvaloniaView.cs index 8de3657283..8177cf1f69 100644 --- a/src/Android/Avalonia.Android/AvaloniaView.cs +++ b/src/Android/Avalonia.Android/AvaloniaView.cs @@ -12,7 +12,7 @@ namespace Avalonia.Android { public class AvaloniaView : FrameLayout { - private readonly EmbeddableControlRoot _root; + private EmbeddableControlRoot _root; private readonly ViewImpl _view; private IDisposable? _timerSubscription; @@ -21,6 +21,11 @@ namespace Avalonia.Android { _view = new ViewImpl(context); AddView(_view.View); + + } + + internal void Prepare () + { _root = new EmbeddableControlRoot(_view); _root.Prepare(); } From c5e6b1979a9f38def1f79ed5c1c361ebe460aff9 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Mon, 7 Mar 2022 12:17:59 +0000 Subject: [PATCH 10/10] fix UseAndroid --- src/Android/Avalonia.Android/AndroidPlatform.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index c19fb021e9..61aa6ce946 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -19,13 +19,10 @@ namespace Avalonia public static T UseAndroid(this T builder) where T : AppBuilderBase, new() { var options = AvaloniaLocator.Current.GetService() ?? new AndroidPlatformOptions(); - - var lifetime = AvaloniaLocator.Current.GetService(); return builder .UseWindowingSubsystem(() => AndroidPlatform.Initialize(options), "Android") - .UseSkia() - .SetupWithLifetime(lifetime); + .UseSkia(); } } }