You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Context: e347cd3
Context: #9962
Context: dotnet/java-interop@dd3c1d0
CoreCLR + `dotnet new maui -sc` (#9962) crashes:
E AndroidRuntime: FATAL EXCEPTION: main
E AndroidRuntime: Process: com.companyname.testmaui, PID: 25497
E AndroidRuntime: android.runtime.JavaProxyThrowable: [System.≈]: Acc_CreateAbstEx, Android.Views.LayoutInflater
E AndroidRuntime: at System.Reflection.RuntimeConstructorInfo.CheckCanCreateInstance + 0x3c(Unknown Source)
E AndroidRuntime: at System.Reflection.RuntimeConstructorInfo.ThrowNoInvokeException + 0x0(Unknown Source)
E AndroidRuntime: at System.Reflection.RuntimeConstructorInfo.Invoke + 0xe(Unknown Source)
E AndroidRuntime: at System.Reflection.ConstructorInfo.Invoke + 0x0(Unknown Source)
E AndroidRuntime: at Microsoft.Android.Runtime.ManagedValueManager.TryCreatePeer + 0x3b(Unknown Source)
E AndroidRuntime: at Java.Interop.JniRuntime+JniValueManager.TryCreatePeerInstance + 0x19(Unknown Source)
E AndroidRuntime: at Java.Interop.JniRuntime+JniValueManager.CreatePeerInstance + 0x5a(Unknown Source)
E AndroidRuntime: at Java.Interop.JniRuntime+JniValueManager.CreatePeer + 0x150(Unknown Source)
E AndroidRuntime: at Java.Interop.JniRuntime+JniValueManager.GetPeer + 0x169(Unknown Source)
E AndroidRuntime: at Java.Lang.Object.GetObject + 0x1d(Unknown Source)
E AndroidRuntime: at Java.Lang.Object._GetObject + 0x19(Unknown Source)
E AndroidRuntime: at Java.Lang.Object.GetObject + 0x1(Unknown Source)
E AndroidRuntime: at Android.Views.LayoutInflater.From + 0x3f(Unknown Source)
E AndroidRuntime: at Microsoft.Maui.Platform.MauiContextExtensions.GetLayoutInflater + 0x2b(Unknown Source)
`AndroidTypeManager` didn't override the
`JniRuntime.JniTypeManager.GetInvokerTypeCore()` method
(dotnet/java-interop@dd3c1d05) and the base implementation of this
method in `JniTypeManager` only looks at `JniTypeSignatureAttribute`
to find the "invoker" type.
.NET for Android bindings don't use `JniTypeSignatureAttribute`, they
use `RegisterAttribute`; for example, consider the abstract
`Android.Views.LayoutInflater` class:
[Register ("android/view/LayoutInflater", DoNotGenerateAcw=true)]
partial class LayoutInflater : Java.Lang.Object {
}
[global::Android.Runtime.Register ("android/view/LayoutInflater", DoNotGenerateAcw=true)]
internal partial class LayoutInflaterInvoker : LayoutInflater {
}
The default `JniRuntime.JniTypeManager.GetInvokerType()` behavior
will not work with .NET for Android bindings.
This has historically been fine because
`AndroidValueManager.CreatePeer()` / `TypeManager.CreateInstance()`
would use `JavaObjectExtensions.GetInvokerType()` to obtain the
`Invoker` type via "pattern-based Reflection", appending `Invoker`
to the abstract type name to obtain a non-abstract constructable type.
That historical behavior changed with e347cd3: CoreCLR doesn't use
`AndroidValueManager`, but instead now uses `ManagedValueManager`,
which *doesn't* call `TypeManager.CreateInstance()` or
`JavaObjectExtensions.GetInvokerType()`. It instead relies on
`JniRuntime.JniTypeManager.GetInvokerType()`, and as that was not
overridden by `AndroidTypeManager`, the invoker for `LayoutInflater`
could not be found, resulting in a `MemberAccessException` as we
attempt to invoke the constructor on the *abstract* `LayoutInflater`
type itself! [^0].
Add an `AndroidTypeManager.GetInvokerTypeCore()` method override
which calls `JavaObjectExtensions.GetInvokerType` when needed to keep
backwards compatibility.
[^0]: The "complete" exception message would be:
Cannot create an instance of Android.Views.LayoutInflater because it is an abstract class.
0 commit comments