From a4bc7b5e6a7892e603878877a8c963fef662c83e Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Sat, 22 Aug 2026 15:56:52 +0100 Subject: [PATCH] build(android): downgrade Avalonia 12 -> 11.3.20 + Avalonia.Maui 11.3.0 WIP: addressing the layer-3 WindowingPlatformStub.NotSupportedException crash on PostIt.Android by downgrading to the Avalonia 11 / Avalonia.Maui 11 stack, where the Android runtime platform layer (IWindowingPlatform) gets properly bound via the MAUI embedding extension instead of being left as a stub. Touched files: - src/PostIt/Directory.Packages.props: - Avalonia 12.1.1 -> 11.3.20 (Avalonia, Avalonia.Android, Avalonia.AvaloniaEdit, Avalonia.Browser, Avalonia.Desktop, Avalonia.Fonts.Inter, Avalonia.Themes.Fluent). - New: Avalonia.Maui 11.3.0. - Microsoft.Maui.Essentials 10.0.100 -> 8.0.100 (aligns with the Microsoft.Maui.Controls 8.0.x family that Avalonia.Maui 11.3.0 pulls transitively). - New: Microsoft.Maui.Controls 8.0.100. - src/PostIt/PostIt.Android/PostIt.Android.csproj: - TargetFramework net10.0-android -> net9.0-android36.0 (Avalonia Android 11.3.20 targets net8.0-android34.0, but the compat-ascending fallback lets us consume from net9.0-android36.0 against the API-36 platform that's already installed locally). - Add Avalonia.Maui PackageReference. - Restore Microsoft.Maui.Essentials PackageReference (left in earlier removal during the MAUI-cause-of-crash hypothesis check). - src/PostIt/PostIt/PostIt.csproj: TargetFramework net10.0 -> net9.0 (must match what PostIt.Android consumes transitively, otherwise the build chain breaks). - src/Yavsc.Abstract/Yavsc.Abstract.csproj: net10.0 -> net9.0 (same reason; six other consumers stay on net10.0 and pick up the new assembly via standard TFM compat). - src/Yavsc.Api.Client/Yavsc.Api.Client.csproj: net10.0 -> net9.0 (same reason). - src/PostIt/PostIt.Android/Application.cs: rewritten as a bare Android.App.Application. Avalonia 11 no longer ships AvaloniaAndroidApplication (that was an Avalonia 12 introduction); the Avalonia init now lives in MainActivity via AvaloniaMainActivity. The class is kept only so the [Application] manifest entry remains. - src/PostIt/PostIt.Android/MainActivity.cs: now inherits AvaloniaMainActivity and overrides CustomizeAppBuilder to chain .UseMaui(this) before .WithInterFont(). AvaloniaMainActivity handles the AvaloniaView initialisation in OnCreate. - src/PostIt/PostIt/Maui/MauiEmbeddingApp.cs (new): empty Microsoft.Maui.Controls.Application used as the embedding host for Avalonia.Maui. The MAUI window it produces is consumed by the Avalonia.Maui embedding pipeline and never surfaces to the user; Avalonia owns the actual visual tree. Build status: 11 errors remaining, all CS0234 / CS0246 against 'Avalonia.Controls.ContentPage'. Avalonia 11 did not ship ContentPage (it's an Avalonia 12 type, presumably for MAUI parity). All seven PostIt pages inherit ContentPage today and need to be reworked to UserControl before the build can complete. Follow-up commit will do that. Reference: AGENTS.md, 'PostIt.Android boot crash sur AVD x86_64 : investigation par couches', couche 3. --- src/PostIt/Directory.Packages.props | 18 +++++----- src/PostIt/PostIt.Android/Application.cs | 32 ++++++++--------- src/PostIt/PostIt.Android/MainActivity.cs | 10 +++++- .../PostIt.Android/PostIt.Android.csproj | 3 +- src/PostIt/PostIt/Maui/MauiEmbeddingApp.cs | 35 +++++++++++++++++++ src/PostIt/PostIt/PostIt.csproj | 2 +- src/Yavsc.Abstract/Yavsc.Abstract.csproj | 2 +- src/Yavsc.Api.Client/Yavsc.Api.Client.csproj | 2 +- 8 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 src/PostIt/PostIt/Maui/MauiEmbeddingApp.cs diff --git a/src/PostIt/Directory.Packages.props b/src/PostIt/Directory.Packages.props index 59b6b600..023d0654 100644 --- a/src/PostIt/Directory.Packages.props +++ b/src/PostIt/Directory.Packages.props @@ -3,18 +3,20 @@ - - - - - - - + + + + + + + + - + + diff --git a/src/PostIt/PostIt.Android/Application.cs b/src/PostIt/PostIt.Android/Application.cs index fb6b08d3..62ace02b 100644 --- a/src/PostIt/PostIt.Android/Application.cs +++ b/src/PostIt/PostIt.Android/Application.cs @@ -1,21 +1,19 @@ -using Android.App; -using Android.Runtime; -using Avalonia; -using Avalonia.Android; +using Android.App; -namespace PostIt.Android +namespace PostIt.Android; + +/// +/// Bare shell for Android. Avalonia +/// 11 initialises its platform services from +/// (which extends AvaloniaMainActivity<App>); no per-Application +/// Avalonia setup is needed here. Kept only so that the [Application] entry +/// stays present in the merged manifest, which the Android runtime expects +/// when the manifest declares a custom android:name in the application tag. +/// +[Application] +public class Application : Android.App.Application { - [Application] - public class Application : AvaloniaAndroidApplication + public Application(nint javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) { - protected Application(nint javaReference, JniHandleOwnership transfer) : base(javaReference, transfer) - { - } - - protected override AppBuilder CustomizeAppBuilder(AppBuilder builder) - { - return base.CustomizeAppBuilder(builder) - .WithInterFont(); - } } -} +} \ No newline at end of file diff --git a/src/PostIt/PostIt.Android/MainActivity.cs b/src/PostIt/PostIt.Android/MainActivity.cs index 1b413a9f..057703a4 100644 --- a/src/PostIt/PostIt.Android/MainActivity.cs +++ b/src/PostIt/PostIt.Android/MainActivity.cs @@ -2,6 +2,7 @@ using Android.App; using Android.Content.PM; using Android.Content; using Avalonia.Android; +using Avalonia; using AndroidX.Emoji2.Text; namespace PostIt.Android; @@ -14,8 +15,15 @@ namespace PostIt.Android; MainLauncher = true, LaunchMode = LaunchMode.SingleTask, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.UiMode)] -public class MainActivity : AvaloniaMainActivity +public class MainActivity : AvaloniaMainActivity { + protected override AppBuilder CustomizeAppBuilder(AppBuilder builder) + { + return base.CustomizeAppBuilder(builder) + .UseMaui(this) + .WithInterFont(); + } + /// /// Strongly-typed handle to the current MainActivity instance, set in /// and consumed by platform services such as diff --git a/src/PostIt/PostIt.Android/PostIt.Android.csproj b/src/PostIt/PostIt.Android/PostIt.Android.csproj index 7669ef62..1f865b07 100644 --- a/src/PostIt/PostIt.Android/PostIt.Android.csproj +++ b/src/PostIt/PostIt.Android/PostIt.Android.csproj @@ -1,7 +1,7 @@ Exe - net10.0-android + net9.0-android36.0 android-arm64;android-x64 23.0.0 @@ -24,6 +24,7 @@ + diff --git a/src/PostIt/PostIt/Maui/MauiEmbeddingApp.cs b/src/PostIt/PostIt/Maui/MauiEmbeddingApp.cs new file mode 100644 index 00000000..4f58b4f2 --- /dev/null +++ b/src/PostIt/PostIt/Maui/MauiEmbeddingApp.cs @@ -0,0 +1,35 @@ +using Microsoft.Maui.Controls; + +namespace PostIt.Maui; + +/// +/// Empty MAUI application registered as the embedding host for +/// Avalonia.Maui. Avalonia.Maui expects a +/// -derived type so that +/// its .UseMaui<TMauiApp>(activity) extension can build the +/// embedding pipeline (services, handlers, IPlatformApplication). +/// +/// We never actually display any MAUI controls — the embedding sits in front +/// of Avalonia so that Avalonia's Android platform layer (which is otherwise +/// bound to a stub on Avalonia 12 / present-but-broken on Avalonia 11 without +/// MAUI) gets the real Android Context and runs the surface view +/// lifecycle correctly. This class exists to satisfy the generic constraint +/// of UseMaui<TMauiApp> and gives MAUI something to attach its +/// handler tree to. +/// +/// Override CreateWindow with a no-op or leave the default; the +/// virtual MAUI window is consumed by Avalonia.Maui's embedding and +/// never surfaces to the user (Avalonia owns the visual tree). +/// +public class MauiEmbeddingApp : Application +{ + public MauiEmbeddingApp() + { + } + + protected override Window CreateWindow(IActivationState? activationState) + { + // No-op window: Avalonia.Maui wraps it and never shows it. + return new Window(); + } +} \ No newline at end of file diff --git a/src/PostIt/PostIt/PostIt.csproj b/src/PostIt/PostIt/PostIt.csproj index 1b48c21f..90fdd837 100644 --- a/src/PostIt/PostIt/PostIt.csproj +++ b/src/PostIt/PostIt/PostIt.csproj @@ -1,6 +1,6 @@ - net10.0 + net9.0 enable latest true diff --git a/src/Yavsc.Abstract/Yavsc.Abstract.csproj b/src/Yavsc.Abstract/Yavsc.Abstract.csproj index 7a4f83ae..2305fc8c 100644 --- a/src/Yavsc.Abstract/Yavsc.Abstract.csproj +++ b/src/Yavsc.Abstract/Yavsc.Abstract.csproj @@ -1,6 +1,6 @@ - net10.0 + net9.0 enable A shared model for a little client/server app, dealing about establishing some contract, between some human client and provider. diff --git a/src/Yavsc.Api.Client/Yavsc.Api.Client.csproj b/src/Yavsc.Api.Client/Yavsc.Api.Client.csproj index ade7ca17..c078789c 100644 --- a/src/Yavsc.Api.Client/Yavsc.Api.Client.csproj +++ b/src/Yavsc.Api.Client/Yavsc.Api.Client.csproj @@ -1,6 +1,6 @@ - net10.0 + net9.0 enable Yavsc.Api.Client Yavsc.Api.Client