Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/Mono.Android/Java.Interop/TypeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -243,15 +243,26 @@ static Exception CreateJavaLocationException ()
Type? type = null;
IntPtr class_ptr = JNIEnv.GetObjectClass (handle);
string? class_name = GetClassName (class_ptr);
List<string>? class_names = null;
lock (TypeManagerMapDictionaries.AccessLock) {
while (class_ptr != IntPtr.Zero && !TypeManagerMapDictionaries.JniToManaged.TryGetValue (class_name, out type)) {

type = GetJavaToManagedType (class_name);
if (type != null) {
TypeManagerMapDictionaries.JniToManaged.Add (class_name, type);

// cache shortcuts for the class names of the subclasses in the hierarchy we just explored
if (class_names is not null) {
foreach (var subclass_name in class_names) {
TypeManagerMapDictionaries.JniToManaged.Add (subclass_name, type);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the type here actually the correct one? It seems like it would be the final type it found and not the one that matches the class_name earlier in the loop.

Do you need to store a (string, Type) tuple, so you have the previous Type instance?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right that it is not an exact match. On the other hand, by inspecting the superclasses in the type hierarchy we should always arraive at the same type. So my idea was to cache this "shortcut".

The only problem I can think of is if we stored this "shortcut", any later call to TypeManager.RegisterType with a more specific mapping would be ignored. This could break dynamic registration. I will need to give this some more thought.

}
}

break;
}

class_names ??= new List<string> ();
class_names.Add (class_name);

IntPtr super_class_ptr = JNIEnv.GetSuperclass (class_ptr);
JNIEnv.DeleteLocalRef (class_ptr);
class_name = null;
Expand Down