Commit dbb0b92
authored
[NativeAOT] Add support for
Context: xamarin/monodroid@1a931e2
`android.app.Application` and `android.app.Instrumentation` are
["special"][0], in terms of app startup and type registration,
because MonoVM is initialized via a `ContentProvider`, which is
constructed *after* `Application` instance is constructed.
In broad terms:
1. `Application` instance is created.
(Specific type is via [`//application/@android:name`][1].)
2. `ContentProvider`s are created, including
`MonoRuntimeProvider` (MonoVM) or
`NativeAotRuntimeProvider` (NativeAOT).
3. `*RuntimeProvider.attachInfo()` invoked, provided (1).
4. `*RuntimeProvider.attachInfo()` does whatever runtime init is
required, e.g. MonoVM's `MonoRuntimeProvider` calls
`MonoPackageManager.LoadApplication()`.
We cannot dispatch Java `native` methods into managed code until
*after* (4) finishes. Meanwhile, we allow C# to subclass
`Android.App.Application` and override methods like
`Application.OnCreate()`:
[Application (Name = "my.MainApplication")]
public partial class MainApplication : Application
{
public override void OnCreate ()
{
base.OnCreate ();
}
}
How does that work?
It works via a leaky abstraction: unlike other types, the
Java Callable Wrapper (JCW) for `Application` and `Instrumentation`
subclasses lacks:
1. A `Runtime.register()` invocation in the static constructor, and
2. A call to `TypeManager.Activate()` in the instance constructor.
Compare an `Activity` JCW:
public /* partial */ class MainActivity extends android.app.Activity {
static {
__md_methods = "…";
mono.android.Runtime.register ("….MainActivity, …", MainActivity.class, __md_methods);
}
public MainActivity ()
{
super ();
if (getClass () == MainActivity.class) {
mono.android.TypeManager.Activate ("….MainActivity, …", "", this, new java.lang.Object[] { });
}
}
}
to an `Application` JCW:
public /* partial */ class MainApplication extends android.app.Application {
{
static {
// mostly empty
}}
public MainApplication ()
{
// Used to provide `Android.App.Application.Context` property
mono.MonoPackageManager.setContext (this);
// No `TypeManager.Activate(…)` call
}
}
Instead of a `Runtime.register()` invocation in the e.g.
`MainApplication` static constructor, `MainApplication` is instead
registered via `ApplicationRegistration.registerApplications()`, which is:
1. Generated via the `<GenerateJavaStubs/>` task, and
2. Invoked from `MonoPackageManager.LoadApplication()`.
"Later", when the Java `Application.onCreate()` method is invoked,
the `Application.n_OnCreate()` marshal method will call
`Java.Lang.Object.GetObject<Application>(…)`. This will look for
the `(IntPtr, JniHandleOwnership)` "activation constructor", which
must be present on the C# type:
public partial class MainApplication : Application
{
public MainApplication (IntPtr handle, JniHandleOwnership transfer)
: base (handle, transfer)
{
}
}
To support `Application` subclasses under NativeAOT, we need to
ensure that the `<GenerateJavaStubs/>` task creates
`ApplicationRegistration.java`, and update
`NativeAotRuntimeProvider` to invoke
`ApplicationRegistration.registerApplications()`. We also need
various changes to `NativeAotValueManager` so that we can create the
`MainApplication` "proxy" instance via the activation constructor.
Other changes:
* Change the package name for `ApplicationRegistration` from
`mono.android` to `net.dot.android`.
* Stop using `AndroidValueManager` and instead copy
[`ManagedValueManager`][2] into `NativeAotValueManager`.
* Allow `CodeGenerationTarget` to be explicitly provided to
`<GenerateJavaStubs/>`, instead of inferring it based on
`$(_AndroidRuntime)`.
[0]: https://learn.microsoft.com/en-us/previous-versions/xamarin/android/internals/architecture#java-activation
[1]: https://developer.android.com/guide/topics/manifest/application-element#nm
[2]: https://github.com/dotnet/java-interop/blob/dd3c1d0514addfe379f050627b3e97493e985da6/src/Java.Runtime.Environment/Java.Interop/ManagedValueManager.csApplication subclasses (#9716)1 parent f3ef4fe commit dbb0b92
File tree
15 files changed
+481
-28
lines changed- samples/NativeAOT
- src
- Xamarin.Android.Build.Tasks
- Microsoft.Android.Sdk/targets
- Resources
- Tasks
- Tests/Xamarin.Android.Build.Tests
- Utilities
- java-runtime
- java
- mono/android
- net/dot/android
15 files changed
+481
-28
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
39 | | - | |
40 | | - | |
| 40 | + | |
| 41 | + | |
41 | 42 | | |
42 | 43 | | |
43 | 44 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
7 | | - | |
8 | | - | |
| 8 | + | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
| 14 | + | |
| 15 | + | |
13 | 16 | | |
14 | 17 | | |
15 | 18 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| 24 | + | |
| 25 | + | |
24 | 26 | | |
25 | 27 | | |
26 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| 16 | + | |
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| 23 | + | |
22 | 24 | | |
23 | 25 | | |
24 | 26 | | |
| |||
0 commit comments