On May 16, 2012, at 3:01 AM, Igor Russkih wrote: > It seems SimpleAdapter is broken (found this in 4.2 alpha), 4.2.1 release > also have this issue:
This is a "regression" that won't be fixed; see: http://lists.ximian.com/pipermail/monodroid/2012-May/010250.html https://bugzilla.xamarin.com/show_bug.cgi?id=2147 The problem is one of preserving object identity between VMs. For example, consider the following code: var list = new JavaList<object>(); JavaList is a java.util.ArrayList, in which every value is referenced in the Java VM. var value = new XElement (/* ... */); list.Add (value); So we've just added an XElement instance to a Java-side list. Okay... So what should the following do: var v = list [0]; object.ReferenceEquals (v, value); Should object.ReferenceEquals() be true or false? Prior to 4.2.1, it would be false, and `v` would refer to an Android.Runtime.JavaObject instance (which isn't even public!), leading to all manner of Reflection-hackery to get back the original value. This is pretty bad. The "good" news was that if it was a Dictionary instead of an XElement, it would be "deep marshaled" into Java: the Dictionary contents would be copied into a java.util.HashMap. The fundamental problem remained, though: `list[0]` would not return `value`, it would (at best) give a separate copy. Worse (for varying values of "worse"), there'd be a _ton_ of global references held during that marshaling operation, none of which would get collected until the entire object graph was collectable by both VMs. In short, it worked, but it was a mess. It led to "bizarre" behavior, and increased gref use. (Truly, I should have fixed that for 4.0, but I wasn't able to carve out the time...) The fix? Use types which won't be implicitly wrapped into an Android.Runtime.JavaObject, i.e. the (public) Android.Runtime collection types. > var settings_data = new List<IDictionary<string, object>>(); var settings_data = new JavaList<IDictionary<string, object>>(); > > sa = Resources.ObtainTypedArray(Resource.Array.settings_text); > sa_icons = > Resources.ObtainTypedArray(Resource.Array.settings_icons); > > for (int i = 0; i < sa.Length(); i++) > { > var item = new Dictionary<string, object>(); var item = new JavaDictionary<string, object>(); > item["text"] = sa.GetString(i); > item["icon"] = sa_icons.GetResourceId(i, 0); > settings_data.Add(item); > } > > this.ListAdapter = new SimpleAdapter(this, settings_data, > Resource.Layout.list_item_icon_text, new String[] { "text", > "icon" }, > new int[] { Resource.Id.text, Resource.Id.icon }); Two changes to two lines should fix your exception. The above still keeps grefs around for longer than absolutely necessary; you can use some `using`s to further decrease the lifetime of the collections, as outlined at: http://lists.ximian.com/pipermail/monodroid/2012-May/010250.html Thanks, - Jon _______________________________________________ Monodroid mailing list Monodroid@lists.ximian.com UNSUBSCRIBE INFORMATION: http://lists.ximian.com/mailman/listinfo/monodroid