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
Xamarin.Android 4.x doesn't properly marshal nested generic types properly. For example, consider the following C# code using SimpleExpandableListAdapter:
// BAD CODE; DO NOT USEvargroupData=newList<IDictionary<string,object>>(){newDictionary<string,object>{{"NAME","Group 1"},{"IS_EVEN","This group is odd"},},};varchildData=newList<IList<IDictionary<string,object>>>(){newList<IDictionary<string,object>>{newDictionary<string,object>{{"NAME","Child 1"},{"IS_EVEN","This group is odd"},},},};mAdapter=newSimpleExpandableListAdapter(this,groupData,Android.Resource.Layout.SimpleExpandableListItem1,newstring[]{"NAME","IS_EVEN"},newint[]{Android.Resource.Id.Text1,Android.Resource.Id.Text2},childData,Android.Resource.Layout.SimpleExpandableListItem2,newstring[]{"NAME","IS_EVEN"},newint[]{Android.Resource.Id.Text1,Android.Resource.Id.Text2});
The problem is that Xamarin.Android incorrectly marshals nested generic types. The List<IDictionary<string, object>> is being marshaled to a java.lang.ArrrayList, but the ArrayList is containing mono.android.runtime.JavaObject instances (which reference the Dictionary<string, object> instances) instead of something that implements java.util.Map, resulting in the following exception:
E/AndroidRuntime( 2991): FATAL EXCEPTION: main
E/AndroidRuntime( 2991): java.lang.ClassCastException: mono.android.runtime.JavaObject cannot be cast to java.util.Map
E/AndroidRuntime( 2991): at android.widget.SimpleExpandableListAdapter.getGroupView(SimpleExpandableListAdapter.java:278)
E/AndroidRuntime( 2991): at android.widget.ExpandableListConnector.getView(ExpandableListConnector.java:446)
E/AndroidRuntime( 2991): at android.widget.AbsListView.obtainView(AbsListView.java:2271)
E/AndroidRuntime( 2991): at android.widget.ListView.makeAndAddView(ListView.java:1769)
E/AndroidRuntime( 2991): at android.widget.ListView.fillDown(ListView.java:672)
E/AndroidRuntime( 2991): at android.widget.ListView.fillFromTop(ListView.java:733)
E/AndroidRuntime( 2991): at android.widget.ListView.layoutChildren(ListView.java:1622)
The workaround is to use the provided Java Collection types instead of the System.Collections.Generic types for the “inner” types. This will result in appropriate Java types when marshaling the instances. (The following code is more complicated than necessary in order to reduce gref lifetimes. It can be simplified to altering the original code via s/List/JavaList/g and s/Dictionary/JavaDictionary/g if gref lifetimes aren't a worry.)
// insert good code hereusing(vargroupData=newJavaList<IDictionary<string,object>>()){using(vargroupEntry=newJavaDictionary<string,object>()){groupEntry.Add("NAME","Group 1");groupEntry.Add("IS_EVEN","This group is odd");groupData.Add(groupEntry);}using(varchildData=newJavaList<IList<IDictionary<string,object>>>()){using(varchildEntry=newJavaList<IDictionary<string,object>>())using(varchildEntryDict=newJavaDictionary<string,object>()){childEntryDict.Add("NAME","Child 1");childEntryDict.Add("IS_EVEN","This child is odd.");childEntry.Add(childEntryDict);childData.Add(childEntry);}mAdapter=newSimpleExpandableListAdapter(this,groupData,Android.Resource.Layout.SimpleExpandableListItem1,newstring[]{"NAME","IS_EVEN"},newint[]{Android.Resource.Id.Text1,Android.Resource.Id.Text2},childData,Android.Resource.Layout.SimpleExpandableListItem2,newstring[]{"NAME","IS_EVEN"},newint[]{Android.Resource.Id.Text1,Android.Resource.Id.Text2});}}
The text was updated successfully, but these errors were encountered:
Context: dotnet/android#6203
Context: https://docs.microsoft.com/en-us/xamarin/android/troubleshooting/troubleshooting#javalangclasscastexception-monoandroidruntimejavaobject-cannot-be-cast-to
Xamarin.Android 4.x doesn't properly marshal nested generic types properly. For example, consider the following C# code using SimpleExpandableListAdapter:
The problem is that Xamarin.Android incorrectly marshals nested generic types. The List<IDictionary<string, object>> is being marshaled to a java.lang.ArrrayList, but the ArrayList is containing mono.android.runtime.JavaObject instances (which reference the Dictionary<string, object> instances) instead of something that implements java.util.Map, resulting in the following exception:
The workaround is to use the provided Java Collection types instead of the System.Collections.Generic types for the “inner” types. This will result in appropriate Java types when marshaling the instances. (The following code is more complicated than necessary in order to reduce gref lifetimes. It can be simplified to altering the original code via s/List/JavaList/g and s/Dictionary/JavaDictionary/g if gref lifetimes aren't a worry.)
The text was updated successfully, but these errors were encountered: