diff --git a/src/Mono.Android/Java.Interop/TypeManager.cs b/src/Mono.Android/Java.Interop/TypeManager.cs index 606051530e9..3f21ea04435 100644 --- a/src/Mono.Android/Java.Interop/TypeManager.cs +++ b/src/Mono.Android/Java.Interop/TypeManager.cs @@ -322,21 +322,26 @@ internal static IJavaPeerable CreateInstance (IntPtr handle, JniHandleOwnership if (!typeSig.IsValid || typeSig.SimpleReference == null) { throw new ArgumentException ($"Could not determine Java type corresponding to `{type.AssemblyQualifiedName}`.", nameof (targetType)); } - JniObjectReference typeClass; + + JniObjectReference typeClass = default; + JniObjectReference handleClass = default; try { - typeClass = JniEnvironment.Types.FindClass (typeSig.SimpleReference); - } catch (Exception e) { - throw new ArgumentException ($"Could not find Java class `{typeSig.SimpleReference}`.", - nameof (targetType), - e); - } + try { + typeClass = JniEnvironment.Types.FindClass (typeSig.SimpleReference); + } catch (Exception e) { + throw new ArgumentException ($"Could not find Java class `{typeSig.SimpleReference}`.", + nameof (targetType), + e); + } - var handleClass = JniEnvironment.Types.GetObjectClass (new JniObjectReference (handle)); - if (!JniEnvironment.Types.IsAssignableFrom (handleClass, typeClass)) { - Logger.Log (LogLevel.Info, "*jonp*", $"# jonp: can't assign `{GetClassName(handleClass.Handle)}` to `{GetClassName(typeClass.Handle)}`"); + handleClass = JniEnvironment.Types.GetObjectClass (new JniObjectReference (handle)); + if (!JniEnvironment.Types.IsAssignableFrom (handleClass, typeClass)) { + Logger.Log (LogLevel.Info, "*jonp*", $"# jonp: can't assign `{GetClassName(handleClass.Handle)}` to `{GetClassName(typeClass.Handle)}`"); + return null; + } + } finally { JniObjectReference.Dispose (ref handleClass); JniObjectReference.Dispose (ref typeClass); - return null; } IJavaPeerable? result = null; diff --git a/tests/Mono.Android-Tests/Android.Content/SharedPreferencesTest.cs b/tests/Mono.Android-Tests/Android.Content/SharedPreferencesTest.cs new file mode 100644 index 00000000000..b47d076f286 --- /dev/null +++ b/tests/Mono.Android-Tests/Android.Content/SharedPreferencesTest.cs @@ -0,0 +1,34 @@ +using System; +using Android.App; +using Android.Content; +using NUnit.Framework; + +namespace Android.ContentTests; + +[TestFixture] +public class SharedPreferencesTest +{ + const string Name = "testpreferences"; + const int Count = 1000; + + ISharedPreferences GetPreferences () => + Application.Context.GetSharedPreferences (Name, FileCreationMode.Private); + + // NOTE: test case on API 23 can trigger: + // art/runtime/indirect_reference_table.cc:115] JNI ERROR (app bug): local reference table overflow + [Test] + public void PutAndGetManyValues () + { + for (int i = 0; i < Count; i++) { + using var prefs = GetPreferences (); + using var editor = prefs.Edit (); + editor.PutString ("key" + i, "value" + i); + editor.Apply (); + } + + for (int i = 0; i < Count; i++) { + using var prefs = GetPreferences (); + Assert.AreEqual ("value" + i, prefs.GetString ("key" + i, null)); + } + } +} diff --git a/tests/Mono.Android-Tests/Mono.Android-Test.Shared.projitems b/tests/Mono.Android-Tests/Mono.Android-Test.Shared.projitems index 7f42b830c7f..0b1ccf1d595 100644 --- a/tests/Mono.Android-Tests/Mono.Android-Test.Shared.projitems +++ b/tests/Mono.Android-Tests/Mono.Android-Test.Shared.projitems @@ -18,6 +18,7 @@ +