Skip to content

Commit 8dd516b

Browse files
committed
[Java.Interop] JniRuntime.JniValueManager method renames.
Rename JniRuntime.JniValueManager.PeekObject() to PeekPeer(). Rationale: consistent terminology (51f7862). What's an "Object"? Rename JniRuntime.JniValueManager.GetSurfacedObjects() to GetSurfacedPeers(). Rationale: consistent terminology (51f7862). What's an "Object"? Change the return type of JniRuntime.JniValueManager.GetSurfacedPeers() from List<WeakReference<IJavaPeerable>> to List<JniSurfacedPeerInfo>>: - public abstract List<WeakReference<IJavaPeerable>> GetSurfacedObjects (); + public abstract List<JniSurfacedPeerInfo> GetSurfacedPeers (); Rationale: While trying to investigate object reference lifetimes in Xamarin.Android, it is not unusual for Java.Interop.Runtime.GetSurfacedObjects() -- which returns a List<WeakReference> -- to contain a WeakReference which has been collected -- i.e. the WeakReference is non-null while WeakReference.Target is null. Meaning I *know* there's an identityHashCode <=> peer mapping, but there's no way -- in the *public* API -- to know what the identityHashCode value *is*. (The identityHashCode value is desired because that's also printed in the GREF log, so with the identityHashCode value I could at least determine what *type* it was.) Which makes it very hard to reason about anything without adding some Console.WriteLine()s into the middle of things, to obtain information that was "lost" because it was never provided. The fix? Provide the identityHashCode value: class JniSurfacedPeerInfo { public int JniIdentityHashCode {get; private set;} public WeakReference<IJavaPeerable> SurfacedPeer {get; private set;} } JniSurfacedPeerInfo.JniIdentityHashCode is the original identityHashCode value for the instance held by JniSurfacedPeerInfo.SurfacedPeer, *even if* the peer has been collected. JniSurfacedPeerInfo is a class so that it can be optionally subclassed.
1 parent 3043d89 commit 8dd516b

File tree

5 files changed

+33
-17
lines changed

5 files changed

+33
-17
lines changed

src/Java.Interop/Java.Interop/JavaProxyObject.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static bool _Equals (IntPtr jnienv, IntPtr n_self, IntPtr n_value)
7272
{
7373
var envp = new JniTransition (jnienv);
7474
try {
75-
var self = (JavaProxyObject) JniEnvironment.Runtime.ValueManager.PeekObject (new JniObjectReference (n_self));
75+
var self = (JavaProxyObject) JniEnvironment.Runtime.ValueManager.PeekPeer (new JniObjectReference (n_self));
7676
var r_value = new JniObjectReference (n_value);
7777
var value = JniEnvironment.Runtime.ValueManager.GetValue (ref r_value, JniObjectReferenceOptions.Copy);
7878
return self.Equals (value);
@@ -91,7 +91,7 @@ static int _GetHashCode (IntPtr jnienv, IntPtr n_self)
9191
{
9292
var envp = new JniTransition (jnienv);
9393
try {
94-
var self = (JavaProxyObject) JniEnvironment.Runtime.ValueManager.PeekObject (new JniObjectReference (n_self));
94+
var self = (JavaProxyObject) JniEnvironment.Runtime.ValueManager.PeekPeer (new JniObjectReference (n_self));
9595
return self.GetHashCode ();
9696
}
9797
catch (Exception e) {
@@ -107,7 +107,7 @@ static IntPtr _ToString (IntPtr jnienv, IntPtr n_self)
107107
{
108108
var envp = new JniTransition (jnienv);
109109
try {
110-
var self = (JavaProxyObject) JniEnvironment.Runtime.ValueManager.PeekObject (new JniObjectReference (n_self));
110+
var self = (JavaProxyObject) JniEnvironment.Runtime.ValueManager.PeekPeer (new JniObjectReference (n_self));
111111
var s = self.ToString ();
112112
var r = JniEnvironment.Strings.NewString (s);
113113
try {

src/Java.Interop/Java.Interop/JniRuntime.JniValueManager.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@
1111

1212
namespace Java.Interop
1313
{
14+
public class JniSurfacedPeerInfo {
15+
16+
public int JniIdentityHashCode {get; private set;}
17+
public WeakReference<IJavaPeerable> SurfacedPeer {get; private set;}
18+
19+
public JniSurfacedPeerInfo (int jniIdentityHashCode, WeakReference<IJavaPeerable> surfacedPeer)
20+
{
21+
JniIdentityHashCode = jniIdentityHashCode;
22+
SurfacedPeer = surfacedPeer;
23+
}
24+
}
25+
1426
partial class JniRuntime
1527
{
1628
partial class CreationOptions {
@@ -58,7 +70,7 @@ protected virtual void Dispose (bool disposing)
5870

5971
public abstract void Finalize (IJavaPeerable value);
6072

61-
public abstract List<WeakReference<IJavaPeerable>> GetSurfacedObjects ();
73+
public abstract List<JniSurfacedPeerInfo> GetSurfacedPeers ();
6274

6375
public void Construct (IJavaPeerable value, ref JniObjectReference reference, JniObjectReferenceOptions options)
6476
{
@@ -153,21 +165,21 @@ public virtual void DisposeUnlessReferenced (IJavaPeerable value)
153165
if (!h.IsValid)
154166
return;
155167

156-
var o = PeekObject (h);
168+
var o = PeekPeer (h);
157169
if (o != null && object.ReferenceEquals (o, value))
158170
return;
159171

160172
Dispose (h, value);
161173
}
162174

163-
public abstract IJavaPeerable PeekObject (JniObjectReference reference);
175+
public abstract IJavaPeerable PeekPeer (JniObjectReference reference);
164176

165177
public object PeekValue (JniObjectReference reference)
166178
{
167179
if (!reference.IsValid)
168180
return null;
169181

170-
var t = PeekObject (reference);
182+
var t = PeekPeer (reference);
171183
if (t == null)
172184
return t;
173185

@@ -195,7 +207,7 @@ protected virtual bool TryUnboxObject (IJavaPeerable value, out object result)
195207

196208
object PeekBoxedObject (JniObjectReference reference)
197209
{
198-
var t = PeekObject (reference);
210+
var t = PeekPeer (reference);
199211
if (t == null)
200212
return null;
201213
object r;

src/Java.Interop/Tests/Java.Interop/JavaObjectTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,18 @@ public void JavaReferencedInstanceSurvivesCollection ()
4646
[Test]
4747
public void UnregisterFromRuntime ()
4848
{
49-
int registeredCount = JniRuntime.CurrentRuntime.ValueManager.GetSurfacedObjects ().Count;
49+
int registeredCount = JniRuntime.CurrentRuntime.ValueManager.GetSurfacedPeers ().Count;
5050
JniObjectReference l;
5151
JavaObject o;
5252
using (o = new JavaObject ()) {
5353
l = o.PeerReference.NewLocalRef ();
5454
Assert.AreEqual (JniObjectReferenceType.Global, o.PeerReference.Type);
55-
Assert.AreEqual (registeredCount+1, JniRuntime.CurrentRuntime.ValueManager.GetSurfacedObjects ().Count);
55+
Assert.AreEqual (registeredCount+1, JniRuntime.CurrentRuntime.ValueManager.GetSurfacedPeers ().Count);
5656
Assert.IsNotNull (JniRuntime.CurrentRuntime.ValueManager.PeekValue (l));
5757
Assert.AreNotSame (l, o.PeerReference);
5858
Assert.AreSame (o, JniRuntime.CurrentRuntime.ValueManager.PeekValue (l));
5959
}
60-
Assert.AreEqual (registeredCount, JniRuntime.CurrentRuntime.ValueManager.GetSurfacedObjects ().Count);
60+
Assert.AreEqual (registeredCount, JniRuntime.CurrentRuntime.ValueManager.GetSurfacedPeers ().Count);
6161
Assert.IsNull (JniRuntime.CurrentRuntime.ValueManager.PeekValue (l));
6262
JniObjectReference.Dispose (ref l);
6363
Assert.Throws<ObjectDisposedException> (() => o.UnregisterFromRuntime ());

src/Java.Interop/Tests/Java.Interop/JniRuntime.JniValueManagerTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ public override void Finalize (IJavaPeerable reference)
5050
{
5151
}
5252

53-
public override List<WeakReference<IJavaPeerable>> GetSurfacedObjects ()
53+
public override List<JniSurfacedPeerInfo> GetSurfacedPeers ()
5454
{
5555
return null;
5656
}
5757

58-
public override IJavaPeerable PeekObject (JniObjectReference reference)
58+
public override IJavaPeerable PeekPeer (JniObjectReference reference)
5959
{
6060
return null;
6161
}

src/Java.Runtime.Environment/Java.Interop/MonoRuntimeValueManager.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,14 @@ protected override void Dispose (bool disposing)
8585
Dictionary<int, WeakReference<IJavaPeerable>> RegisteredInstances = new Dictionary<int, WeakReference<IJavaPeerable>>();
8686

8787

88-
public override List<WeakReference<IJavaPeerable>> GetSurfacedObjects ()
88+
public override List<JniSurfacedPeerInfo> GetSurfacedPeers ()
8989
{
9090
lock (RegisteredInstances) {
91-
return RegisteredInstances.Values.ToList ();
91+
var peers = new List<JniSurfacedPeerInfo> (RegisteredInstances.Count);
92+
foreach (var e in RegisteredInstances) {
93+
peers.Add (new JniSurfacedPeerInfo (e.Key, e.Value));
94+
}
95+
return peers;
9296
}
9397
}
9498

@@ -97,7 +101,7 @@ public override void Add (IJavaPeerable value)
97101
var r = value.PeerReference;
98102
if (!r.IsValid)
99103
throw new ObjectDisposedException (value.GetType ().FullName);
100-
var o = PeekObject (value.PeerReference);
104+
var o = PeekPeer (value.PeerReference);
101105
if (o != null)
102106
return;
103107

@@ -147,7 +151,7 @@ public override void Remove (IJavaPeerable value)
147151
}
148152
}
149153

150-
public override IJavaPeerable PeekObject (JniObjectReference reference)
154+
public override IJavaPeerable PeekPeer (JniObjectReference reference)
151155
{
152156
if (!reference.IsValid)
153157
return null;

0 commit comments

Comments
 (0)