-
Notifications
You must be signed in to change notification settings - Fork 555
[Mono.Android] Add ManagedValueManager, use with CoreCLR #9973
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Context: #9962 Context: dotnet/java-interop@5852e6e `dotnet new maui -sc` fails under CoreCLR: D AndroidRuntime: Shutting down VM E AndroidRuntime: FATAL EXCEPTION: main E AndroidRuntime: Process: com.companyname.dotnetnewmauisamplecontent, PID: 6548 E AndroidRuntime: android.runtime.JavaProxyThrowable: [System.InvalidOperationException]: InvalidOperation_HandleIsNotInitialized E AndroidRuntime: at System.WeakReference`1.SetTarget + 0x18(Unknown Source) E AndroidRuntime: at Microsoft.Maui.ApplicationModel.ActivityLifecycleContextListener.set_Activity + 0x0(Unknown Source) E AndroidRuntime: at Microsoft.Maui.ApplicationModel.ActivityLifecycleContextListener.Android.App.Application.IActivityLifecycleCallbacks.OnActivityResumed + 0x0(Unknown Source) E AndroidRuntime: at Android.App.Application+IActivityLifecycleCallbacksInvoker.n_OnActivityResumed_Landroid_app_Activity_ + 0xe(Unknown Source) E AndroidRuntime: at crc64ba438d8f48cf7e75.ActivityLifecycleContextListener.n_onActivityResumed(Native Method) E AndroidRuntime: at crc64ba438d8f48cf7e75.ActivityLifecycleContextListener.onActivityResumed(ActivityLifecycleContextListener.java:42) E AndroidRuntime: at android.app.Application.dispatchActivityResumed(Application.java:431) E AndroidRuntime: at android.app.Activity.dispatchActivityResumed(Activity.java:1434) E AndroidRuntime: at android.app.Activity.onResume(Activity.java:1995) E AndroidRuntime: at androidx.fragment.app.FragmentActivity.onResume(FragmentActivity.java:309) E AndroidRuntime: at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1531) E AndroidRuntime: at android.app.Activity.performResume(Activity.java:8422) E AndroidRuntime: at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4793) E AndroidRuntime: at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4836) E AndroidRuntime: at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:54) E AndroidRuntime: at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45) E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2308) E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106) E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:201) E AndroidRuntime: at android.os.Looper.loop(Looper.java:288) E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7898) E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) *A* likely explanation is that we're using the wrong `JniRuntime.JniValueManager` when running under CoreCLR: we're using `AndroidValueManager`, which uses `WeakReference<T>` to hold `IJavaPeerable` instances. As CoreCLR does not have a GC bridge, this means that any `IJavaPeerable` instance which is kept alive only by Java code -- such as `Activity` instances! -- will be collected, which at minimum will be "surprising". Fortunately, we already have a `JniRuntime.JniValueManager` which retains strong references to every created `IJavaPeerable` instance: `NativeAotValueManager`! The problem is that `NativeAotValueManager` is in `Microsoft.Android.Runtime.NativeAOT.dll`, which isn't usable from a CoreCLR context. Move `NativeAotValueManager` into `Mono.Android.dll`, renaming it `ManagedValueManager`. Update `JNIEnvInit.Initialize()` to use `ManagedValueManager` when running under CoreCLR. Relatedly: dotnet/java-interop@5852e6e3 obsoleted `JniRuntime.CreationOptions.ClassLoader_LoadClass_id`, so update `AndroidRuntime` and `AndroidRuntimeOptions` to no longer use that.
CI was emitting a new warning: /Users/builder/azdo/_work/10/s/xamarin-android/src/Mono.Android/Microsoft.Android.Runtime/ManagedValueManager.cs(236,3): Trim analysis warning IL2072: Microsoft.Android.Runtime.ManagedValueManager.ActivateViaReflection(JniObjectReference, ConstructorInfo, Object[]): 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in call to 'System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject(Type)'. The return value of method 'System.Reflection.MemberInfo.DeclaringType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. Suppress the warnings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{ | ||
const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors; | ||
|
||
readonly JniRuntime.JniTypeManager TypeManager; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird, I guess this is unused now.
Will this get "backported" to |
Context: #9962 Context: dotnet/java-interop@5852e6e `dotnet new maui -sc` fails under CoreCLR: D AndroidRuntime: Shutting down VM E AndroidRuntime: FATAL EXCEPTION: main E AndroidRuntime: Process: com.companyname.dotnetnewmauisamplecontent, PID: 6548 E AndroidRuntime: android.runtime.JavaProxyThrowable: [System.InvalidOperationException]: InvalidOperation_HandleIsNotInitialized E AndroidRuntime: at System.WeakReference`1.SetTarget + 0x18(Unknown Source) E AndroidRuntime: at Microsoft.Maui.ApplicationModel.ActivityLifecycleContextListener.set_Activity + 0x0(Unknown Source) E AndroidRuntime: at Microsoft.Maui.ApplicationModel.ActivityLifecycleContextListener.Android.App.Application.IActivityLifecycleCallbacks.OnActivityResumed + 0x0(Unknown Source) E AndroidRuntime: at Android.App.Application+IActivityLifecycleCallbacksInvoker.n_OnActivityResumed_Landroid_app_Activity_ + 0xe(Unknown Source) E AndroidRuntime: at crc64ba438d8f48cf7e75.ActivityLifecycleContextListener.n_onActivityResumed(Native Method) E AndroidRuntime: at crc64ba438d8f48cf7e75.ActivityLifecycleContextListener.onActivityResumed(ActivityLifecycleContextListener.java:42) E AndroidRuntime: at android.app.Application.dispatchActivityResumed(Application.java:431) E AndroidRuntime: at android.app.Activity.dispatchActivityResumed(Activity.java:1434) E AndroidRuntime: at android.app.Activity.onResume(Activity.java:1995) E AndroidRuntime: at androidx.fragment.app.FragmentActivity.onResume(FragmentActivity.java:309) E AndroidRuntime: at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1531) E AndroidRuntime: at android.app.Activity.performResume(Activity.java:8422) E AndroidRuntime: at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4793) E AndroidRuntime: at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4836) E AndroidRuntime: at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:54) E AndroidRuntime: at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45) E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:176) E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2308) E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106) E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:201) E AndroidRuntime: at android.os.Looper.loop(Looper.java:288) E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:7898) E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936) *A* likely explanation is that we're using the wrong `JniRuntime.JniValueManager` when running under CoreCLR: we're using `AndroidValueManager`, which uses `WeakReference<T>` to hold `IJavaPeerable` instances. As CoreCLR does not have a GC bridge, this means that any `IJavaPeerable` instance which is kept alive only by Java code -- such as `Activity` instances! -- will be collected, which at minimum will be "surprising". Fortunately, we already have a `JniRuntime.JniValueManager` which retains strong references to every created `IJavaPeerable` instance: `NativeAotValueManager`! The problem is that `NativeAotValueManager` is in `Microsoft.Android.Runtime.NativeAOT.dll`, which isn't usable from a CoreCLR context. Move `NativeAotValueManager` into `Mono.Android.dll`, renaming it `ManagedValueManager`. Update `JNIEnvInit.Initialize()` to use `ManagedValueManager` when running under CoreCLR. Relatedly: dotnet/java-interop@5852e6e3 obsoleted `JniRuntime.CreationOptions.ClassLoader_LoadClass_id`, so update `AndroidRuntime` and `AndroidRuntimeOptions` to no longer use that. * Suppress IL2072 CI was emitting a new warning: /Users/builder/azdo/_work/10/s/xamarin-android/src/Mono.Android/Microsoft.Android.Runtime/ManagedValueManager.cs(236,3): Trim analysis warning IL2072: Microsoft.Android.Runtime.ManagedValueManager.ActivateViaReflection(JniObjectReference, ConstructorInfo, Object[]): 'type' argument does not satisfy 'DynamicallyAccessedMemberTypes.PublicConstructors', 'DynamicallyAccessedMemberTypes.NonPublicConstructors' in call to 'System.Runtime.CompilerServices.RuntimeHelpers.GetUninitializedObject(Type)'. The return value of method 'System.Reflection.MemberInfo.DeclaringType.get' does not have matching annotations. The source value must declare at least the same requirements as those declared on the target location it is assigned to. Suppress the warnings.
It should be there now: |
Context: dotnet/android#9973 We introduced a new `internal` type in `Mono.Android.dll`: namespace Microsoft.Android.Runtime; class ManagedValueManager : JniRuntime.JniValueManager Causes various C# compiler errors in dotnet/maui: D:\src\maui\src\Essentials\src\AppActions\AppActions.shared.cs(62,28): error CS0234: The type or namespace name 'Content' does not exist in the namespace 'Microsoft.Android' (are you missing an assembly reference?) At some point in .NET 10 (or future), we will likely introduce a *public* type in `Microsoft.Android` namespace. This means MAUI's codebase will need to be fixed in a .NET 10 timeframe, so instead of: Android.Content.Context content; This works: using Android.Content; //... Context content; Because the `using Android.Content;` directive is scoped *outside* of a `Microsoft.*` namespace. We don't anticipate this to be a problem with customers, because they aren't writing code in `Microsoft.*` namespaces. I generally took the approach: * Use `using Android.Content;` if possible. * Use `global::` if that caused other conflicts. * Use `using AView = Android.Views.View;` in Microsoft.Maui.Controls or other places this is commonly used. * Update `#if __ANDROID__` to `#if ANDROID` in a few places.
Context: dotnet/android#9973 We introduced a new `internal` type in `Mono.Android.dll`: namespace Microsoft.Android.Runtime; class ManagedValueManager : JniRuntime.JniValueManager Causes various C# compiler errors in dotnet/maui: D:\src\maui\src\Essentials\src\AppActions\AppActions.shared.cs(62,28): error CS0234: The type or namespace name 'Content' does not exist in the namespace 'Microsoft.Android' (are you missing an assembly reference?) At some point in .NET 10 (or future), we will likely introduce a *public* type in `Microsoft.Android` namespace. This means MAUI's codebase will need to be fixed in a .NET 10 timeframe, so instead of: Android.Content.Context content; This works: using Android.Content; //... Context content; Because the `using Android.Content;` directive is scoped *outside* of a `Microsoft.*` namespace. We don't anticipate this to be a problem with customers, because they aren't writing code in `Microsoft.*` namespaces. I generally took the approach: * Use `using Android.Content;` if possible. * Use `global::` if that caused other conflicts. * Use `using AView = Android.Views.View;` in Microsoft.Maui.Controls or other places this is commonly used. * Update `#if __ANDROID__` to `#if ANDROID` in a few places.
Context: #9962
Context: dotnet/java-interop@5852e6e
dotnet new maui -sc
fails under CoreCLR:A likely explanation is that we're using the wrong
JniRuntime.JniValueManager
when running under CoreCLR: we're usingAndroidValueManager
, which usesWeakReference<T>
to holdIJavaPeerable
instances. As CoreCLR does not have a GC bridge, this means that anyIJavaPeerable
instance which is kept alive only by Java code -- such asActivity
instances! -- will be collected, which at minimum will be "surprising".Fortunately, we already have a
JniRuntime.JniValueManager
which retains strong references to every createdIJavaPeerable
instance:NativeAotValueManager
!The problem is that
NativeAotValueManager
is inMicrosoft.Android.Runtime.NativeAOT.dll
, which isn't usable from a CoreCLR context.Move
NativeAotValueManager
intoMono.Android.dll
, renaming itManagedValueManager
.Update
JNIEnvInit.Initialize()
to useManagedValueManager
when running under CoreCLR.Relatedly: dotnet/java-interop@5852e6e3 obsoleted
JniRuntime.CreationOptions.ClassLoader_LoadClass_id
, so updateAndroidRuntime
andAndroidRuntimeOptions
to no longer use that.