Thanks for explanation, Jon.
Actually I've tried JavaList/Dict in first, but made a mistake:
Instead of
var settings_data = new JavaList<IDictionary<string,object>>();
used
var settings_data = new
JavaList<JavaDictionary<string,object>>();
And that failed to cast.
Thanks for prompt response!
Igor
On Wed, May 16, 2012 at 7:55 PM, Jonathan Pryor <[email protected]> wrote:
> 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
> [email protected]
>
> UNSUBSCRIBE INFORMATION:
> http://lists.ximian.com/mailman/listinfo/monodroid
>
_______________________________________________
Monodroid mailing list
[email protected]
UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid