Add IActivityApplicationLifetime for android (#18893)
* add lifetime with view factory on android * rename android lifetime interface * add warning when using ISingleViewApplicationLifetime for android, set current main activity reference on OnResume * fix nit
This commit is contained in:
@@ -44,6 +44,10 @@ namespace ControlCatalog
|
||||
{
|
||||
desktopLifetime.MainWindow = new MainWindow { DataContext = new MainWindowViewModel() };
|
||||
}
|
||||
else if(ApplicationLifetime is IActivityApplicationLifetime singleViewFactoryApplicationLifetime)
|
||||
{
|
||||
singleViewFactoryApplicationLifetime.MainViewFactory = () => new MainView { DataContext = new MainWindowViewModel() };
|
||||
}
|
||||
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewLifetime)
|
||||
{
|
||||
singleViewLifetime.MainView = new MainView { DataContext = new MainWindowViewModel() };
|
||||
@@ -97,6 +101,10 @@ namespace ControlCatalog
|
||||
newWindow.Show();
|
||||
oldWindow?.Close();
|
||||
}
|
||||
else if (app.ApplicationLifetime is IActivityApplicationLifetime singleViewFactoryApplicationLifetime)
|
||||
{
|
||||
singleViewFactoryApplicationLifetime.MainViewFactory = () => new MainView { DataContext = new MainWindowViewModel() };
|
||||
}
|
||||
else if (app.ApplicationLifetime is ISingleViewApplicationLifetime singleViewLifetime)
|
||||
{
|
||||
singleViewLifetime.MainView = new MainView();
|
||||
|
||||
@@ -19,6 +19,10 @@ namespace SafeAreaDemo
|
||||
{
|
||||
desktop.MainWindow = new MainWindow();
|
||||
}
|
||||
else if (ApplicationLifetime is IActivityApplicationLifetime singleViewFactoryApplicationLifetime)
|
||||
{
|
||||
singleViewFactoryApplicationLifetime.MainViewFactory = () => new MainView();
|
||||
}
|
||||
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform)
|
||||
{
|
||||
singleViewPlatform.MainView = new MainView();
|
||||
|
||||
@@ -21,6 +21,10 @@ public class App : Application
|
||||
{
|
||||
desktopLifetime.MainWindow = new MainWindow();
|
||||
}
|
||||
else if (ApplicationLifetime is IActivityApplicationLifetime singleViewFactoryApplicationLifetime)
|
||||
{
|
||||
singleViewFactoryApplicationLifetime.MainViewFactory = () => new MainView();
|
||||
}
|
||||
else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewLifetime)
|
||||
{
|
||||
singleViewLifetime.MainView = new MainView();
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using Avalonia.Logging;
|
||||
|
||||
namespace Avalonia.Android;
|
||||
|
||||
internal class ApplicationLifetime : IActivityApplicationLifetime, ISingleViewApplicationLifetime
|
||||
{
|
||||
private Control? _mainView;
|
||||
|
||||
public Func<Control>? MainViewFactory { get; set; }
|
||||
|
||||
public Control? MainView
|
||||
{
|
||||
get => _mainView; set
|
||||
{
|
||||
_mainView = value;
|
||||
|
||||
Logger.TryGet(LogEventLevel.Warning, LogArea.AndroidPlatform)?.Log(this, "ISingleViewApplicationLifetime.MainView is not fully supported on Android." +
|
||||
" Consider setting IActivityApplicationLifetime.MainViewFactory.");
|
||||
if (_mainView != null)
|
||||
MainViewFactory = () => _mainView;
|
||||
else
|
||||
MainViewFactory = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,13 +9,13 @@ namespace Avalonia.Android
|
||||
{
|
||||
internal interface IAndroidApplication
|
||||
{
|
||||
SingleViewLifetime? Lifetime { get; set; }
|
||||
ApplicationLifetime? Lifetime { get; set; }
|
||||
}
|
||||
|
||||
public class AvaloniaAndroidApplication<TApp> : global::Android.App.Application, IAndroidApplication
|
||||
where TApp : Application, new()
|
||||
{
|
||||
SingleViewLifetime? IAndroidApplication.Lifetime { get; set; }
|
||||
ApplicationLifetime? IAndroidApplication.Lifetime { get; set; }
|
||||
|
||||
protected AvaloniaAndroidApplication(nint javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
|
||||
{
|
||||
@@ -32,7 +32,7 @@ namespace Avalonia.Android
|
||||
var builder = CreateAppBuilder();
|
||||
builder = CustomizeAppBuilder(builder);
|
||||
|
||||
var lifetime = new SingleViewLifetime();
|
||||
var lifetime = new ApplicationLifetime();
|
||||
|
||||
((IAndroidApplication)this).Lifetime = lifetime;
|
||||
|
||||
|
||||
@@ -12,14 +12,20 @@ public class AvaloniaMainActivity : AvaloniaActivity
|
||||
{
|
||||
if (Application is IAndroidApplication application && application.Lifetime is { } lifetime)
|
||||
{
|
||||
initialContent ??= lifetime.MainView;
|
||||
initialContent ??= lifetime.MainViewFactory?.Invoke();
|
||||
|
||||
_view = new AvaloniaView(this) { Content = initialContent };
|
||||
lifetime.Activity = this;
|
||||
_view = new AvaloniaView(this);
|
||||
|
||||
Content = initialContent;
|
||||
}
|
||||
|
||||
if (_view is null)
|
||||
throw new InvalidOperationException("Unknown error: AvaloniaView initialization has failed.");
|
||||
}
|
||||
|
||||
protected override void OnResume()
|
||||
{
|
||||
base.OnResume();
|
||||
|
||||
if (Avalonia.Application.Current?.TryGetFeature<IActivatableLifetime>()
|
||||
is AndroidActivatableLifetime activatableLifetime)
|
||||
@@ -28,6 +34,17 @@ public class AvaloniaMainActivity : AvaloniaActivity
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
base.OnDestroy();
|
||||
|
||||
if (Avalonia.Application.Current?.TryGetFeature<IActivatableLifetime>()
|
||||
is AndroidActivatableLifetime activatableLifetime && activatableLifetime.CurrentMainActivity == this)
|
||||
{
|
||||
activatableLifetime.CurrentMainActivity = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual AppBuilder CreateAppBuilder() => AppBuilder.Configure<Application>().UseAndroid();
|
||||
protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder;
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
|
||||
namespace Avalonia.Android;
|
||||
|
||||
internal class SingleViewLifetime : ISingleViewApplicationLifetime, ISingleTopLevelApplicationLifetime
|
||||
{
|
||||
private Control? _mainView;
|
||||
private AvaloniaMainActivity? _activity;
|
||||
|
||||
/// <summary>
|
||||
/// Since Main Activity can be swapped, we should adjust lifetime as well.
|
||||
/// </summary>
|
||||
public AvaloniaMainActivity Activity
|
||||
{
|
||||
[return: MaybeNull] get => _activity!;
|
||||
internal set
|
||||
{
|
||||
if (_activity != null)
|
||||
{
|
||||
_activity.Content = null;
|
||||
}
|
||||
_activity = value;
|
||||
_activity.Content = _mainView;
|
||||
}
|
||||
}
|
||||
|
||||
public Control? MainView
|
||||
{
|
||||
get => _mainView;
|
||||
set
|
||||
{
|
||||
if (_mainView != value)
|
||||
{
|
||||
_mainView = value;
|
||||
if (_activity != null)
|
||||
{
|
||||
_activity.Content = _mainView;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TopLevel? TopLevel => _activity?._view?.TopLevel;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using Avalonia.Metadata;
|
||||
|
||||
namespace Avalonia.Controls.ApplicationLifetimes
|
||||
{
|
||||
[NotClientImplementable]
|
||||
public interface IActivityApplicationLifetime : IApplicationLifetime
|
||||
{
|
||||
Func<Control>? MainViewFactory { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user