Bug 7396 - castclassexception when trying GetParcelableArrayList
Summary: castclassexception when trying GetParcelableArrayList
Status: RESOLVED FEATURE
Alias: None
Product: Android
Classification: Xamarin
Component: BCL Class Libraries ()
Version: 4.2.x
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2012-09-22 03:15 UTC by Denis
Modified: 2012-10-01 07:13 UTC (History)
2 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FEATURE

Comment 1 Atsushi Eno 2012-09-24 04:33:43 UTC
Could you provide 1) the acual code for "arr" (it seems to be a collection of some type but we cannot reproduce things without this) and 2) the actual exception at "Exception there" ?
Comment 2 Denis 2012-09-24 04:45:29 UTC
1. For example from first activity we start second

Intent intent = new Intent(this, typeof(SecondActivity));
List<IParcelable> msgs = new List<IParcelable>();
                    for (int i = 0; i < arr.Length;i++ )
                    {
                        ContentValues values = new ContentValues();
                        values.Put("Title", arr[i].Message);
                        values.Put("Date", arr[i].Date.ToString());
                        msgs.Add(values);
                    }
                    Bundle b = new Bundle();
                    b.PutParcelableArrayList("events",msgs);
intent.PutExtra("b", b);

in SecondActivity.OnCreate:
Bundle b = Intent.Extras;
var arr = b.GetParcelableArrayList("events"); 

2. System.InvalidCastException: Cannot cast from source type to destination type.
  at SwissRadar.Fragments.EventsFragment.OnReceiveResult (int,Android.OS.Bundle) [0x00019] in c:\Users\Denis\Documents\Projects\SwissRadar\SwissRadar\EventsFragment.cs:57

  at SwissRadar.Utils.RemoteReciever.OnReceiveResult (int,Android.OS.Bundle) [0x0000f] in c:\Users\Denis\Documents\Projects\SwissRadar\SwissRadar\RemoteReciever.cs:32

  at Android.OS.ResultReceiver.n_OnReceiveResult_ILandroid_os_Bundle_ (intptr,intptr,int,intptr) [0x00010] in /Users/builder/data/lanes/monodroid-mac-monodroid-4.2.6-branch/632e6ddf/source/monodroid/src/Mono.Android/platforms/android-4/src/generated/Android.OS.ResultReceiver.cs:118

  at (wrapper dynamic-method) object.69d4b077-4cc4-4bca-a0cd-57a16008e8db (intptr,intptr,int,intptr) <IL 0x00018, 0x00023>
Comment 3 Atsushi Eno 2012-09-24 05:29:29 UTC
I tried to reproduce the issue based on your code, but I couldn't. I had to "guess" how "arr" is declared and things are filled, but this repro contains some alternative code that should replicate that.

So I don't think PutParcelableArrayList() is problematic. Could you provide more specific code that actually reproduce the issue?

Activity1.cs ---------------------------------

using System;
using System.Collections.Generic;
using System;

using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;

namespace Bug7396
{
	[Activity (Label = "Bug7396", MainLauncher = true)]
	public class Activity1 : Activity
	{
		int count = 1;

		protected override void OnCreate (Bundle bundle)
		{
			base.OnCreate (bundle);

			// Set our view from the "main" layout resource
			SetContentView (Resource.Layout.Main);

			// Get our button from the layout resource,
			// and attach an event to it
			Button button = FindViewById<Button> (Resource.Id.myButton);
			
			button.Click += delegate {
				Intent intent = new Intent(this, typeof (Activity2));
				List<IParcelable> msgs = new List<IParcelable>();
				var arr = new ContentValues [10];
				for (int i = 0; i < arr.Length;i++ )
				{
					ContentValues values = new ContentValues();
					values.Put("Title", "some title");//arr[i].Message);
					values.Put("Date", "2012-09-24");//arr[i].Date.ToString());
					msgs.Add(values);
				}
				Bundle b = new Bundle ();
				b.PutParcelableArrayList("events", msgs);
				intent.PutExtra ("b", b);

				StartActivity (intent);
			};
		}
	}
}


Activity2.cs ---------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;

namespace Bug7396
{
	[Activity (Label = "Activity2")]			
	public class Activity2 : Activity
	{
		protected override void OnCreate (Bundle bundle)
		{
			base.OnCreate (bundle);

			Bundle b = Intent.Extras.Get ("b").JavaCast<Bundle> ();
			var arr = b.GetParcelableArrayList ("events"); 
			foreach (IParcelable item in arr) {
				var v = item.JavaCast<ContentValues> ();
				Console.WriteLine (v.Get ("Title"));
				Console.WriteLine (v.Get ("Date"));
			}
		}
	}
}
Comment 4 Denis 2012-09-24 06:56:11 UTC
yes, my mistake..

I tried get 

IList<IParcelable> arr = (IList<IParcelable>)		                          resultData.GetParcelableArrayList("events");

but get classcastexception, but GetParcelableArrayList must return IList. I don't understand why i get exception. With var everything ok
Comment 5 Atsushi Eno 2012-10-01 07:13:18 UTC
No, (I'm not sure if your "resultData" is either Bundle or Intent but) GetParcelableArrayList(string) must NOT return generic IList<IParcelable>. It returns IList implementation.

http://androidapi.xamarin.com/?link=M:Android.Content.Intent.GetParcelableArrayListExtra

The reason why it does not return .NET generics is, here Java generics does not *actually* exist (so called Java generics type erasure) and it returns just a list, so we also return IList. The resulting IList implementation is hence non-generic list and your cast is supposed to fail.