Open
Description
Android framework version
Other
Affected platform version
.NET 10, NativeAOT
Description
For NativeAOT-friendly support, there are some generator changes to emit methods like:
[global::System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
static void n_OnCreate_Landroid_os_Bundle_Landroid_os_PersistableBundle_ (IntPtr jnienv, IntPtr native__this, IntPtr native_savedInstanceState, IntPtr native_persistentState)
{
if (!global::Java.Interop.JniEnvironment.BeginMarshalMethod (jnienv, out var __envp, out var __r))
return;
try {
var __this = global::Java.Lang.Object.GetObject<Android.App.Activity> (jnienv, native__this, JniHandleOwnership.DoNotTransfer)!;
var savedInstanceState = global::Java.Lang.Object.GetObject<Android.OS.Bundle> (native_savedInstanceState, JniHandleOwnership.DoNotTransfer);
var persistentState = global::Java.Lang.Object.GetObject<Android.OS.PersistableBundle> (native_persistentState, JniHandleOwnership.DoNotTransfer);
__this.OnCreate (savedInstanceState, persistentState);
} catch (global::System.Exception __e) {
__r.OnUserUnhandledException (ref __envp, __e);
} finally {
global::Java.Interop.JniEnvironment.EndMarshalMethod (ref __envp);
}
}
These use:
- New
Java.Interop.dll
methods that are only present in .NET 10 OnUserUnhandledException()
relies on a feature that only works in ICorDebug (not Mono debugger)
I have a PR here that builds this repo with a net10.0-android
tfm:
So, how do we build .NET MAUI for .NET 10 and rely on new AndroidX binding packages?
Idea 1
Multi-target for .NET 8, .NET 9, .NET 10.
This would require:
- .NET 10 Android workload to support .NET 8 for a period of time
Potential blocker:
- We would build all frameworks with either a preview or nightly Roslyn (C# compiler). If you have a .NET 10 SDK, you get the .NET 10 C# compiler for the other target frameworks.
- Alternatively build the repo twice w/ stable and preview .NET SDKs, and somehow "merge" the .NET 10 assemblies inside.
Idea 2
-
Build a "preview" set of AndroidX and GPS NuGets with a version number like
-preview-net10
or similar. -
Publish these to NuGet.org.
-
.NET MAUI relies on these for .NET 10.
Potential blocker:
- It appears that "binderator" (unsure of exact details) emits supported ranges of dependent versions between the various AndroidX packages.
- This would need to be removed, to only depend on the .NET 10 preview versions.
- Customers could see the
-preview-net10
packages and try to use them. - Customers might have trouble trying out .NET 10, updating from .NET 9 to 10?
Conclusion
I am somewhat leaning towards no. 2, but @jpobst or @Redth open to other ideas?
Activity
jpobst commentedon Jan 29, 2025
To be precise, .NET MAUI 10 will run on today's packages. However the NativeAOT feature (when it exists) will not work without
net10.0-android
AndroidX packages.My hunch is that (2) isn't going to work in practice.
Let's say we have:
NuGet considers
1.0.0
as "higher" than1.0.0-preview
and will likely choose the stable version whenever it can. Given the massive amount of transitive packages in the AndroidX ecosystem, I think it's very likely a stable one will get chosen somewhere.Additional issues:
Xamarin.AndroidX.Security.SecurityCrypto
1.1.0.2-alpha06
, not sure how we could force a dependency on1.1.0.2-alpha06-preview-net10
that doesn't get broken when we release new unstable versions.I think (1) is probably the better way to go. We would need to decide if we're concerned about using a .NET 10 preview CSC to compile our
net8.0-android
libraries. If we are, then likely a significant amount of work would be required to build the ecosystem twice and merge them into a single NuGet."Idea 3" would be a custom NuGet feed. This would require extra effort on the user's part.
We probably need to decide what timeframe(s) we are talking about. For example, a custom feed is probably good enough for the first several previews as the expectation is that users will have to do quite a bit of extra effort to try it out. (And they will likely just be doing toy "hello world" apps. No one could try to port their existing "real" apps because the ecosystem support won't exist yet.) As .NET previews mature, maybe we are more comfortable with doing (1) with the Roslyn caveat.
We will also likely need build warnings/errors that can detect when you're attempting to use NativeAOT with non-supported binding libraries.
jonathanpeppers commentedon Jan 29, 2025
For this problem, do we normally just bump a
.1
across all the packages anyway? It would be 1.0.1-preview?Is there already something built into this repo for doing this? To "align" all the packages?
I don't think we can require a custom feed for the
maui
template.dotnet new
immediately restores now, and sodotnet new maui
would fail.jpobst commentedon Jan 29, 2025
We do not publish preview packages, so it isn't something that has come up. But then you have the same problem when we publish a new
1.0.1
stable version and everyone's local preview MAUI 10 is asking for1.0.1-preview
.Yes, you can run
dotnet cake -t=bump-config
We could add a
NuGet.config
to the .NET 10 preview maui template, which might not be a horrible idea.moljac commentedon Jan 30, 2025
My initial idea (gut feeling) was - Option 1
How big problem would that represent?
I am afraid Option 2 will cause confusion and tons of issues.
Option 3 (nuget feed) would also be feasible solution.
This would be a problem if stable 1.0.1 is published. Usually we bump build number (4th numerical part)
jonathanpeppers commentedon Jan 30, 2025
@moljac are we OK to use a preview roslyn for the stable .NET 8 and 9 packs?
Or do you propose to build the repo twice and somehow "merge in" the .NET 10 assemblies?
moljac commentedon Jan 30, 2025
I think this would be OK.
I think this would be overly complicated and we don't have that much resources.
jpobst commentedon Jan 30, 2025
I was thinking if we do go down this route, the easiest way may be to:
<TargetFrameworks>net8.0-android;net10.0-android</TargetFrameworks>
NuGet packages with .NET 10 SDK<TargetFrameworks>net8.0-android</TargetFrameworks>
with .NET 8 SDKnet8.0-android
.dll
in each NuGetThis way the NuGet package would already be correctly built and we just change one file in it.
This feels easier than:
net10.0-android
assembliesnet8.0-android
assemblies.nuspec
files to create a combined packagemoljac commentedon Jan 31, 2025
Would that mean to replace for example
Xamarin.AndroidX.Lifecycle.Common.dll
(and others) built for/withnet8.0
?Makes sense.
We'll need to shuffle
generated
folder and play with file copy.That is much simpler.
jonathanpeppers commentedon Jan 31, 2025
Ok, what if this is the plan:
net10.0-android
net8.0-android
Then we actually don't even need .NET 10 to support .NET 8?
jpobst commentedon Jan 31, 2025
Yep
I feel like that is considerably harder to set up than building
<TargetFrameworks>net8.0-android;net10.0-android</TargetFrameworks>
and replacing thenet8.0-android
.dll
file later.Note this need would be temporary. Once we can drop .NET 8 after May we would only be building .NET 9/10.
[Xamarin.Android.Build.Tasks] temporarily support .NET 8 in .NET 10
[Xamarin.Android.Build.Tasks] temporarily support .NET 8 in .NET 10 (#…