diff --git a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/TypeMapAssemblyEmitter.cs b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/TypeMapAssemblyEmitter.cs index 34bfd15a9b6..101eec9618c 100644 --- a/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/TypeMapAssemblyEmitter.cs +++ b/src/Microsoft.Android.Sdk.TrimmableTypeMap/Generator/TypeMapAssemblyEmitter.cs @@ -207,7 +207,12 @@ void EmitTypeReferences () void EmitMemberReferences () { _baseCtorRef = _pe.AddMemberRef (_javaPeerProxyRef, ".ctor", - sig => sig.MethodSignature (isInstanceMethod: true).Parameters (0, rt => rt.Void (), p => { })); + sig => sig.MethodSignature (isInstanceMethod: true).Parameters (2, + rt => rt.Void (), + p => { + p.AddParameter ().Type ().Type (_systemTypeRef, false); + p.AddParameter ().Type ().Type (_systemTypeRef, false); + })); _getTypeFromHandleRef = _pe.AddMemberRef (_systemTypeRef, "GetTypeFromHandle", sig => sig.MethodSignature ().Parameters (1, @@ -360,12 +365,24 @@ void EmitProxyType (JavaPeerProxyData proxy, Dictionary sig.MethodSignature (isInstanceMethod: true).Parameters (0, rt => rt.Void (), p => { }), encoder => { encoder.OpCode (ILOpCode.Ldarg_0); + // arg 1: typeof(TargetType) + encoder.OpCode (ILOpCode.Ldtoken); + encoder.Token (_pe.ResolveTypeRef (proxy.TargetType)); + encoder.Call (_getTypeFromHandleRef); + // arg 2: typeof(InvokerType) or null + if (proxy.InvokerType != null) { + encoder.OpCode (ILOpCode.Ldtoken); + encoder.Token (_pe.ResolveTypeRef (proxy.InvokerType)); + encoder.Call (_getTypeFromHandleRef); + } else { + encoder.OpCode (ILOpCode.Ldnull); + } encoder.Call (_baseCtorRef); encoder.OpCode (ILOpCode.Ret); }); @@ -373,16 +390,6 @@ void EmitProxyType (JavaPeerProxyData proxy, Dictionary sig.MethodSignature (isInstanceMethod: true).Parameters (0, - rt => rt.Type ().Type (_systemTypeRef, false), - p => { }), - encoder => { - encoder.OpCode (ILOpCode.Ldtoken); - encoder.Token (handle); - encoder.Call (_getTypeFromHandleRef); - encoder.OpCode (ILOpCode.Ret); - }); - } - MethodDefinitionHandle EmitUcoMethod (UcoMethodData uco) { var jniParams = JniSignatureHelper.ParseParameterTypes (uco.JniSignature); diff --git a/src/Mono.Android/Java.Interop/JavaPeerProxy.cs b/src/Mono.Android/Java.Interop/JavaPeerProxy.cs index 0fe4b72cc48..08bc2c538f1 100644 --- a/src/Mono.Android/Java.Interop/JavaPeerProxy.cs +++ b/src/Mono.Android/Java.Interop/JavaPeerProxy.cs @@ -18,32 +18,42 @@ namespace Java.Interop [AttributeUsage (AttributeTargets.Class | AttributeTargets.Interface, Inherited = false, AllowMultiple = false)] public abstract class JavaPeerProxy : Attribute { + /// + /// Initializes a new proxy with the specified target and invoker types. + /// + /// The managed peer type this proxy represents. + /// The invoker type for interfaces/abstract classes, or null for concrete types. + protected JavaPeerProxy ( + Type targetType, + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + Type? invokerType) + { + TargetType = targetType; + InvokerType = invokerType; + } + /// /// Creates an instance of the target type using the JNI handle and ownership semantics. /// This replaces the reflection-based constructor invocation used in the legacy path. /// - /// The JNI object reference handle. - /// How to handle JNI reference ownership. - /// A new instance of the target type wrapping the JNI handle, or null if activation is not supported. public abstract IJavaPeerable? CreateInstance (IntPtr handle, JniHandleOwnership transfer); /// /// Gets the target .NET type that this proxy represents. /// - public abstract Type TargetType { get; } + public Type TargetType { get; } /// /// Gets the invoker type for interfaces and abstract classes. /// Returns null for concrete types that can be directly instantiated. /// [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] - public virtual Type? InvokerType => null; + public Type? InvokerType { get; } /// /// Gets a factory for creating containers (arrays, collections) of the target type. /// Enables AOT-safe creation of generic collections without MakeGenericType(). /// - /// A factory for creating containers of the target type, or null if not supported. public virtual JavaPeerContainerFactory? GetContainerFactory () => null; } @@ -59,7 +69,9 @@ public abstract class JavaPeerProxy< T > : JavaPeerProxy where T : class, IJavaPeerable { - public override Type TargetType => typeof (T); + protected JavaPeerProxy ( + [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] + Type? invokerType) : base (typeof (T), invokerType) { } public override JavaPeerContainerFactory GetContainerFactory () => JavaPeerContainerFactory.Instance;