Browse Source

Seperate Avalonia lifecycle from android activity

pull/9154/head
Emmanuel Hansen 3 years ago
parent
commit
ebdb4e1974
  1. 12
      samples/ControlCatalog.Android/MainActivity.cs
  2. 13
      samples/ControlCatalog.Android/SplashActivity.cs
  3. 66
      src/Android/Avalonia.Android/AvaloniaActivity.cs
  4. 34
      src/Android/Avalonia.Android/AvaloniaSplashActivity.cs
  5. 2
      src/Android/Avalonia.Android/AvaloniaView.cs
  6. 6
      src/Android/Avalonia.Android/OpenGL/GlPlatformSurface.cs
  7. 7
      src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
  8. 26
      src/Android/Avalonia.Android/SingleViewLifetime.cs

12
samples/ControlCatalog.Android/MainActivity.cs

@ -5,16 +5,8 @@ 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<App>
[Activity(Label = "ControlCatalog.Android", Theme = "@style/MyTheme.NoActionBar", Icon = "@drawable/icon", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
public class MainActivity : AvaloniaActivity
{
protected override AppBuilder CustomizeAppBuilder(AppBuilder builder)
{
return base.CustomizeAppBuilder(builder)
.AfterSetup(_ =>
{
Pages.EmbedSample.Implementation = new EmbedSampleAndroid();
});
}
}
}

13
samples/ControlCatalog.Android/SplashActivity.cs

@ -1,12 +1,23 @@
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Avalonia.Android;
namespace ControlCatalog.Android
{
[Activity(Theme = "@style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]
public class SplashActivity : Activity
public class SplashActivity : AvaloniaSplashActivity<App>
{
protected override Avalonia.AppBuilder CustomizeAppBuilder(Avalonia.AppBuilder builder)
{
return base.CustomizeAppBuilder(builder)
.AfterSetup(_ =>
{
Pages.EmbedSample.Implementation = new EmbedSampleAndroid();
});
}
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);

66
src/Android/Avalonia.Android/AvaloniaActivity.cs

@ -1,62 +1,42 @@
using System;
using Android.App;
using Android.Content;
using Android.Content.Res;
using Android.OS;
using Android.Runtime;
using AndroidX.AppCompat.App;
using Android.Content.Res;
using AndroidX.Lifecycle;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls;
using Android.Runtime;
using Android.App;
using Android.Content;
using System;
namespace Avalonia.Android
{
public abstract class AvaloniaActivity : AppCompatActivity
{
internal class SingleViewLifetime : ISingleViewApplicationLifetime
{
public AvaloniaView View { get; internal set; }
public Control MainView
{
get => (Control)View.Content;
set => View.Content = value;
}
}
internal Action<int, Result, Intent> ActivityResult;
internal AvaloniaView View;
internal AvaloniaViewModel _viewModel;
protected abstract AppBuilder CreateAppBuilder();
protected override void OnCreate(Bundle savedInstanceState)
{
var builder = CreateAppBuilder();
_viewModel = new ViewModelProvider(this).Get(Java.Lang.Class.FromType(typeof(AvaloniaViewModel))) as AvaloniaViewModel;
var lifetime = new SingleViewLifetime();
builder.AfterSetup(x =>
View = new AvaloniaView(this);
if (_viewModel.Content != null)
{
_viewModel = new ViewModelProvider(this).Get(Java.Lang.Class.FromType(typeof(AvaloniaViewModel))) as AvaloniaViewModel;
View.Content = _viewModel.Content;
}
View = new AvaloniaView(this);
if (_viewModel.Content != null)
{
View.Content = _viewModel.Content;
}
View.Prepare();
SetContentView(View);
if (Avalonia.Application.Current.ApplicationLifetime is SingleViewLifetime lifetime)
{
lifetime.View = View;
View.Prepare();
});
builder.SetupWithLifetime(lifetime);
}
base.OnCreate(savedInstanceState);
SetContentView(View);
}
public object Content
{
get
@ -90,16 +70,4 @@ namespace Avalonia.Android
ActivityResult?.Invoke(requestCode, resultCode, data);
}
}
public abstract class AvaloniaActivity<TApp> : AvaloniaActivity where TApp : Application, new()
{
protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder.UseAndroid();
protected override AppBuilder CreateAppBuilder()
{
var builder = AppBuilder.Configure<TApp>();
return CustomizeAppBuilder(builder);
}
}
}

34
src/Android/Avalonia.Android/AvaloniaSplashActivity.cs

@ -0,0 +1,34 @@
using Android.OS;
using AndroidX.AppCompat.App;
using AndroidX.Lifecycle;
namespace Avalonia.Android
{
public abstract class AvaloniaSplashActivity : AppCompatActivity
{
protected abstract AppBuilder CreateAppBuilder();
protected override void OnCreate(Bundle? savedInstanceState)
{
base.OnCreate(savedInstanceState);
var builder = CreateAppBuilder();
var lifetime = new SingleViewLifetime();
builder.SetupWithLifetime(lifetime);
}
}
public abstract class AvaloniaSplashActivity<TApp> : AvaloniaSplashActivity where TApp : Application, new()
{
protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder.UseAndroid();
protected override AppBuilder CreateAppBuilder()
{
var builder = AppBuilder.Configure<TApp>();
return CustomizeAppBuilder(builder);
}
}
}

2
src/Android/Avalonia.Android/AvaloniaView.cs

@ -74,7 +74,7 @@ namespace Avalonia.Android
class ViewImpl : TopLevelImpl
{
public ViewImpl(AvaloniaView avaloniaView) : base(avaloniaView)
public ViewImpl(AvaloniaView avaloniaView) : base(avaloniaView, true)
{
View.Focusable = true;
View.FocusChange += ViewImpl_FocusChange;

6
src/Android/Avalonia.Android/OpenGL/GlPlatformSurface.cs

@ -1,4 +1,5 @@
using Avalonia.OpenGL.Egl;
using Avalonia.OpenGL;
using Avalonia.OpenGL.Egl;
using Avalonia.OpenGL.Surfaces;
namespace Avalonia.Android.OpenGL
@ -19,7 +20,8 @@ namespace Avalonia.Android.OpenGL
public static GlPlatformSurface TryCreate(IEglWindowGlPlatformSurfaceInfo info)
{
if (EglPlatformOpenGlInterface.TryCreate() is EglPlatformOpenGlInterface egl)
var feature = AvaloniaLocator.Current.GetService<IPlatformOpenGlInterface>();
if (feature is EglPlatformOpenGlInterface egl)
{
return new GlPlatformSurface(egl, info);
}

7
src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs

@ -3,20 +3,14 @@ using System.Collections.Generic;
using Android.Content;
using Android.Graphics;
using Android.Media.TV;
using Android.OS;
using Android.Runtime;
using Android.Text;
using Android.Views;
using Android.Views.InputMethods;
using Android.Widget;
using Avalonia.Android.OpenGL;
using Avalonia.Android.Platform.Input;
using Avalonia.Android.Platform.Specific;
using Avalonia.Android.Platform.Specific.Helpers;
using Avalonia.Android.Platform.Storage;
using Avalonia.Controls;
using Avalonia.Controls.Documents;
using Avalonia.Controls.Platform;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Input;
@ -29,7 +23,6 @@ using Avalonia.Platform.Storage;
using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
using Java.Lang;
using static System.Net.Mime.MediaTypeNames;
namespace Avalonia.Android.Platform.SkiaPlatform
{

26
src/Android/Avalonia.Android/SingleViewLifetime.cs

@ -0,0 +1,26 @@
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
namespace Avalonia.Android
{
internal class SingleViewLifetime : ISingleViewApplicationLifetime
{
private AvaloniaView _view;
public AvaloniaView View
{
get => _view; internal set
{
if (_view != null)
{
_view.Content = null;
_view.Dispose();
}
_view = value;
_view.Content = MainView;
}
}
public Control MainView { get; set; }
}
}
Loading…
Cancel
Save