Skip to content

Commit 310dee1

Browse files
[Mono.Android] Java.Lang.Object.GetObject<T>() implementation
Context: #9630 Context: dotnet/java-interop#1295 As an alternative to #9630... For NativeAOT support, implement `Java.Lang.Object.GetObject()` using the new `JniRuntime.JniValueManager.GetPeer()` method. This also cleans up a few things if `Java.Lang.Object` introduces an internal `DynamicallyAccessedMemberTypes Constructors` field.
1 parent 3856e62 commit 310dee1

File tree

16 files changed

+40
-34
lines changed

16 files changed

+40
-34
lines changed

src/Mono.Android/Android.App/Activity.cs

-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ namespace Android.App {
66

77
partial class Activity {
88

9-
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
10-
119
public T? FindViewById<
1210
[DynamicallyAccessedMembers (Constructors)]
1311
T

src/Mono.Android/Android.App/Dialog.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ protected Dialog (Android.Content.Context context, bool cancelable, EventHandler
1010
: this (context, cancelable, new Android.Content.IDialogInterfaceOnCancelListenerImplementor () { Handler = cancelHandler }) {}
1111

1212
public T? FindViewById<
13-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
13+
[DynamicallyAccessedMembers (Constructors)]
1414
T
1515
> (int id)
1616
where T : Android.Views.View

src/Mono.Android/Android.App/FragmentManager.cs

-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
#if ANDROID_11
66
namespace Android.App {
77
public partial class FragmentManager {
8-
const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
9-
108
public T? FindFragmentById<
119
[DynamicallyAccessedMembers (Constructors)]
1210
T

src/Mono.Android/Android.OS/AsyncTask.cs

-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ public abstract class AsyncTask<
1818
TResult
1919
> : AsyncTask {
2020

21-
const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
22-
2321
static IntPtr java_class_handle;
2422
internal static IntPtr class_ref {
2523
get {

src/Mono.Android/Android.Runtime/JNIEnv.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,13 @@ public static void CopyArray (IntPtr src, string[] dest)
662662
AssertIsJavaObject (type);
663663

664664
IntPtr elem = GetObjectArrayElement (source, index);
665-
return Java.Lang.Object.GetObject (elem, JniHandleOwnership.TransferLocalRef, type);
665+
return GetObject (elem, type);
666+
667+
// FIXME: Since a Dictionary<Type, Func> is used here, the trimmer will not be able to properly analyze `Type t`
668+
// error IL2111: Method 'lambda expression' with parameters or return value with `DynamicallyAccessedMembersAttribute` is accessed via reflection. Trimmer can't guarantee availability of the requirements of the method.
669+
[UnconditionalSuppressMessage ("Trimming", "IL2067", Justification = "FIXME: https://github.com/xamarin/xamarin-android/issues/8724")]
670+
static object? GetObject (IntPtr e, Type t) =>
671+
Java.Lang.Object.GetObject (e, JniHandleOwnership.TransferLocalRef, t);
666672
} },
667673
{ typeof (Array), (type, source, index) => {
668674
IntPtr elem = GetObjectArrayElement (source, index);

src/Mono.Android/Android.Runtime/JavaArray.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4-
4+
using System.Diagnostics.CodeAnalysis;
55

66
namespace Android.Runtime {
77

88
[Register ("mono/android/runtime/JavaArray", DoNotGenerateAcw=true)]
9-
public sealed class JavaArray<T> : Java.Lang.Object, IList<T> {
9+
public sealed class JavaArray<
10+
[DynamicallyAccessedMembers (Constructors)]
11+
T
12+
> : Java.Lang.Object, IList<T> {
1013

1114
public JavaArray (IntPtr handle, JniHandleOwnership transfer)
1215
: base (handle, transfer)

src/Mono.Android/Android.Runtime/JavaCollection.cs

-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ namespace Android.Runtime {
1414
// java.util.Collection allows null values
1515
public class JavaCollection : Java.Lang.Object, System.Collections.ICollection {
1616

17-
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
18-
1917
internal static IntPtr collection_class = JNIEnv.FindClass ("java/util/Collection");
2018

2119
internal static IntPtr id_add;

src/Mono.Android/Android.Runtime/JavaDictionary.cs

-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ namespace Android.Runtime {
1212
// java.util.HashMap allows null keys and values
1313
public class JavaDictionary : Java.Lang.Object, System.Collections.IDictionary {
1414

15-
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
16-
1715
class DictionaryEnumerator : IDictionaryEnumerator {
1816

1917
IEnumerator simple_enumerator;

src/Mono.Android/Android.Runtime/JavaList.cs

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ namespace Android.Runtime {
1010
// java.util.ArrayList allows null values
1111
public partial class JavaList : Java.Lang.Object, System.Collections.IList {
1212

13-
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
1413
internal static readonly JniPeerMembers list_members = new XAPeerMembers ("java/util/List", typeof (JavaList), isInterface: true);
1514

1615
//

src/Mono.Android/Android.Runtime/JavaSet.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ public static IntPtr ToLocalJniHandle (ICollection? items)
269269
[Register ("java/util/HashSet", DoNotGenerateAcw=true)]
270270
// java.util.HashSet allows null
271271
public class JavaSet<
272-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
272+
[DynamicallyAccessedMembers (Constructors)]
273273
T
274274
> : JavaSet, ICollection<T> {
275275

src/Mono.Android/Android.Util/SparseArray.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Android.Util
99
{
1010
[Register ("android/util/SparseArray", DoNotGenerateAcw=true)]
1111
public partial class SparseArray<
12-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
12+
[DynamicallyAccessedMembers (Constructors)]
1313
E
1414
> : SparseArray
1515
{

src/Mono.Android/Android.Views/View.cs

-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ public enum SystemUiFlags {
1313
#endif
1414

1515
public partial class View {
16-
17-
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
18-
1916
#if ANDROID_16
2017
[Obsolete ("This method uses wrong enum type. Please use PerformAccessibilityAction(Action) instead.")]
2118
public bool PerformAccessibilityAction (GlobalAction action, Bundle arguments)

src/Mono.Android/Android.Views/Window.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Android.Views {
77
partial class Window {
88

99
public T? FindViewById<
10-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
10+
[DynamicallyAccessedMembers (Constructors)]
1111
T
1212
> (int id)
1313
where T : Android.Views.View

src/Mono.Android/Android.Widget/AdapterView.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public event EventHandler ItemSelectionCleared {
5151

5252
[Register ("android/widget/AdapterView", DoNotGenerateAcw=true)]
5353
public abstract class AdapterView<
54-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
54+
[DynamicallyAccessedMembers (Constructors)]
5555
T
5656
> : AdapterView where T : IAdapter {
5757

src/Mono.Android/Android.Widget/ArrayAdapter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Android.Widget {
99

1010
[Register ("android/widget/ArrayAdapter", DoNotGenerateAcw=true)]
1111
public partial class ArrayAdapter<
12-
[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)]
12+
[DynamicallyAccessedMembers (Constructors)]
1313
T
1414
> : ArrayAdapter {
1515

src/Mono.Android/Java.Lang/Object.cs

+22-11
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ namespace Java.Lang {
1616
[Serializable]
1717
public partial class Object : global::Java.Interop.JavaObject, IJavaObject, IJavaObjectEx
1818
{
19+
internal const DynamicallyAccessedMemberTypes Constructors = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors;
20+
1921
IntPtr IJavaObjectEx.ToLocalJniHandle ()
2022
{
2123
lock (this) {
@@ -130,39 +132,48 @@ protected void SetHandle (IntPtr value, JniHandleOwnership transfer)
130132
return (T?)PeekObject (handle, typeof (T));
131133
}
132134

133-
public static T? GetObject<T> (IntPtr jnienv, IntPtr handle, JniHandleOwnership transfer)
135+
public static T? GetObject<
136+
[DynamicallyAccessedMembers (Constructors)]
137+
T
138+
> (IntPtr jnienv, IntPtr handle, JniHandleOwnership transfer)
134139
where T : class, IJavaObject
135140
{
136141
JNIEnv.CheckHandle (jnienv);
137142
return GetObject<T> (handle, transfer);
138143
}
139144

140-
public static T? GetObject<T> (IntPtr handle, JniHandleOwnership transfer)
145+
public static T? GetObject<
146+
[DynamicallyAccessedMembers (Constructors)]
147+
T
148+
> (IntPtr handle, JniHandleOwnership transfer)
141149
where T : class, IJavaObject
142150
{
143151
return _GetObject<T>(handle, transfer);
144152
}
145153

146-
internal static T? _GetObject<T> (IntPtr handle, JniHandleOwnership transfer)
154+
internal static T? _GetObject<
155+
[DynamicallyAccessedMembers (Constructors)]
156+
T
157+
> (IntPtr handle, JniHandleOwnership transfer)
147158
{
148159
if (handle == IntPtr.Zero)
149160
return default (T);
150161

151162
return (T?) GetObject (handle, transfer, typeof (T));
152163
}
153164

154-
internal static IJavaPeerable? GetObject (IntPtr handle, JniHandleOwnership transfer, Type? type = null)
165+
internal static IJavaPeerable? GetObject (
166+
IntPtr handle,
167+
JniHandleOwnership transfer,
168+
[DynamicallyAccessedMembers (Constructors)]
169+
Type? type = null)
155170
{
156171
if (handle == IntPtr.Zero)
157172
return null;
158173

159-
var r = PeekObject (handle, type);
160-
if (r != null) {
161-
JNIEnv.DeleteRef (handle, transfer);
162-
return r;
163-
}
164-
165-
return Java.Interop.TypeManager.CreateInstance (handle, transfer, type);
174+
var r = JNIEnvInit.ValueManager!.GetPeer (new JniObjectReference (handle), type);
175+
JNIEnv.DeleteRef (handle, transfer);
176+
return r;
166177
}
167178

168179
[EditorBrowsable (EditorBrowsableState.Never)]

0 commit comments

Comments
 (0)