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 <j...@xamarin.com> 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
> Monodroid@lists.ximian.com
>
> UNSUBSCRIBE INFORMATION:
> http://lists.ximian.com/mailman/listinfo/monodroid
>
_______________________________________________
Monodroid mailing list
Monodroid@lists.ximian.com

UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid

Reply via email to