You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on May 29, 2024. It is now read-only.
[Mono.Android] Prefer BaseAdapter over ArrayAdapter.
BaseAdapter/BaseAdapter<T> should be preferred over
ArrayAdapter/ArrayAdapter<T> when the element type is NOT a
Java.Lang.Object subclass. Non-Java.Lang.Object types will be
implicitly wrapped in a Java.Lang.Object subclass, requiring a GREF
for each element stored within the ArrayAdapter, and many Android
targets have a limited GREF count.
Using BaseAdapter allows for using a GREF only for each _displayed_
item instead of for each item.
From: http://lists.ximian.com/pipermail/monodroid/2012-August/011730.html
On Aug 9, 2012, at 10:50 AM, subsembly <a.selle at subsembly.com> wrote:
> I am trying to understand what exactly happens when I am using an
> Android.Widget.ArrayAdapter<string> for my list views and spinners.
> Considering the following sample code from an Activity:
>
> string[] vs = new string[] { "one", "two", "three" }
> ArrayAdapter<string> aa = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleSpinnerItem, vs);
> Spinner s = (Spinner)this.FindViewById(Resource.Id.myspinner);
> s.Adapter = aa;
>
> I know that on the Java side, the ArrayAdapter needs a Java list
> with Java objects. How is Mono for Android converting my C# string
> to the Java objects that Java needs?
Lots of JNI glue. ;-)
The array is "deep copied" into Java.
The string[] is marshaled into a Java-side array via JNIEnv.NewObjectArray(),
which in this case will allocate a Java-side java.lang.String[], then copy each
element of the C# string[] into the Java String[] via JNIEnv.NewString(). No
grefs are required.
If you were instead dealing with a builtin type such as `int`, the values would
instead be converted into a java.lang.Integer[], and the values are (again)
"deep copied." No grefs are required.
When using a Java.Lang.Object subclass, a new Java-side array will be created,
and each element of the Java-side array will reference the Android Callable
Wrapper for the C# instance. Each instance will have a gref, but they'd have a
gref _anyway_; the underlying Java array will not have a gref.
When using any other managed type, a new Java-side java.lang.Object[] array
will be created, with each element referring to an internal
mono.android.JavaObject instance which will reference the managed instance.
Each JavaObject instance will also take out a gref.
> Later in my code when I use
>
> Java.Lang.Object o = s.SelectedItem;
>
> How does the returned Java object relate to my original string?
`o` will be a Java.Lang.String instance, which will contain a copy of your
original string value. This will also cause a gref to be allocated (for
referential equality); if grefs are an issue, you'll want to dispose of it ASAP.
> And how do I get back to the original string?
The original string instance? You don't. (Thus `object.ReferenceEquals()` is out.)
The original string value? `o.ToString()`. You can thus do:
string item;
using (var o = s.SelectedItem)
item = o.ToString();
> Finally: Is there a better (faster, less memory using) way than using an ArrayAdapter<string> at all?
The tradeoff is in performance. For strings, ArrayAdapter<string> should be
good -- the entire collection is stored in Java, making Java-side object lookup
fast. There's some overhead in duplicated strings, but there's no way to avoid
this: as soon as Java code calls ArrayAdapter<String>.getItem(), it'll get a
Java-side copy of the string anyway; there's no way to avoid that copy.
If you were dealing with some other type, specifically a managed type, you'd
want to consider forgoing ArrayAdapter<T> altogether and using BaseAdapter<T>
instead. This will cause item lookup to be _slower_ (due to the transition to
managed code), but gref counts will also be lower and there will be fewer
instances allocated.
- Jon
0 commit comments