Photo by pxhere.com

How to use Parcelable with Xamarin.Android

When you develop a Xamarin.Android application, you often need to pass parameters between activities.

Posted by Damien Aicheh on May 26, 2018 · 11 mins

What is a Parcelable

When you develop a Xamarin.Android application, you often need to pass parameters between activities. Android provides you different way to achieve that, one of these is to use Parcelables.

Parcelables give you the ability to pass an entire model between two activities in Android applications.

To start this tutorial, you will find a starter project on Github.

This project is a simple Xamarin.Android project with one .NET Standard library for the shared code. The goal of this tutorial is to pass a model between two activities.

In our scenario we have a first activity : MainActivity to be original ;) that show us the first and last name of a user. We have all the data about the user in this activity and we want to pass it to the second activity : DetailActivity.

The model that we will pass between the activities is a User :

public class User
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public int Age { get; set; }

    public string Address { get; set; }

    public string City { get; set; }

    public string Country { get; set; }
}

If you launch the app now, you will get a simple page, with the first and last name displayed and a button. Nothing fancy for now.

Create the Parcelable

In our Xamarin.Android project we need to create a parcelable class, that will allow you to pass the User from one activity to the other.

Let’s create a new folder called : Parcelables and in this one, create a new file : UserParcelable

First we need to implement Java.Lang.Object and IParcelable :

public class UserParcelable : Java.Lang.Object, IParcelable
{
    public UserParcelable()
    {
    }

    public int DescribeContents()
    {
        throw new NotImplementedException();
    }

    public void WriteToParcel(Parcel dest, [GeneratedEnum] ParcelableWriteFlags flags)
    {
        throw new NotImplementedException();
    }
}

The default constructor is mandatory for the Parcelable Creator class that we will see later in this tutorial.

Passing an object using Parcelable consist in serializing and deserializing it. It’s the same concept as using JSON when you call an API.

Let’s first add a User object to our class.

public User User { get; set; }

Serialization

To pass data with in the Parcelable we need to use a Parcel, it contains all the data and object references that we want to send.

The WriteToParcel method is the serialization part :

public void WriteToParcel(Parcel dest, [GeneratedEnum] ParcelableWriteFlags flags)
{
    dest.WriteLong(User.Id);
    dest.WriteString(User.FirstName);
    dest.WriteString(User.LastName);
    dest.WriteInt(User.Age);
    dest.WriteString(User.Address);
    dest.WriteString(User.City);
    dest.WriteString(User.Country);
}

As we can see above, we need to write each parameters to the Parcel object depending on their type (Long, Int, String…)

The DescribeContents method describe the kinds of complex objects contained in this Parcelable. In our example, because we only have simple types in our User model, we just need to write return 0.

public int DescribeContents()
{
    return 0;
}

Deserialization

We now need to create the Parcelable constructor and re-assign all the parameters of our User model in the same order that we defined in the WriteToParcel method :

private UserParcelable(Parcel parcel)
{
    User = new User
    {
        Id = parcel.ReadLong(),
        FirstName = parcel.ReadString(),
        LastName = parcel.ReadString(),
        Age = parcel.ReadInt(),
        Address = parcel.ReadString(),
        City = parcel.ReadString(),
        Country = parcel.ReadString()
    };
}

Instanciation

Now we need to create another class that will create instances of our UserParcelable class.

Here a generic class that you can add in your Parcelables folder, so you will be able to use it for every new Parcelable you will create.

public class GenericParcelableCreator<T> : Java.Lang.Object, IParcelableCreator where T : Java.Lang.Object, new()
{
    /// <summary>
    /// Function for the creation of a parcel.
    /// </summary>
    private readonly Func<Parcel, T> _createFunc;

    /// <summary>
    /// Initialize an instance of the GenericParcelableCreator.
    /// </summary>
    public GenericParcelableCreator(Func<Parcel, T> createFromParcelFunc)
    {
        _createFunc = createFromParcelFunc;
    }

    /// <summary>
    /// Create a parcelable from a parcel.
    /// </summary>
    public Java.Lang.Object CreateFromParcel(Parcel parcel)
    {
        return _createFunc(parcel);
    }

    /// <summary>
    /// Create an array from the parcelable class.
    /// </summary>
    public Java.Lang.Object[] NewArray(int size)
    {
        return new T[size];
    }
}

So we can use this class in our UserParcelable class :

private static readonly GenericParcelableCreator<UserParcelable> _creator
            = new GenericParcelableCreator<UserParcelable>((parcel) => new UserParcelable(parcel));

[ExportField("CREATOR")]
public static GenericParcelableCreator<UserParcelable> GetCreator()
{
    return _creator;
}

This will create an instance of the Parcelable object for us.

Using the parcelable

Now that we are ready to pass data between our two pages, let’s get back to the MainActivity and in the SeeMoreBtn_Click method that I have already prepared for you, we have to create a Parcelable and send it to the DetailActivity :

Intent intent = new Intent(this, typeof(DetailActivity));

UserParcelable parcelable = new UserParcelable();
parcelable.User = _user;
intent.PutExtra(DetailActivity.UserParcelableExtra, parcelable);

StartActivity(intent);

In the DetailActivity we receive our User object, to do that, add these lines in the OnCreate method :

UserParcelable parcelable = (UserParcelable)Intent.GetParcelableExtra(UserParcelableExtra);
UpdateView(parcelable.User);

If you build the project you will get this error :

Error XA4210: You need to add a reference to Mono.Android.Export.dll when you use ExportAttribute or ExportFieldAttribute. (XA4210)

As the error mentions, we need to edit the references of our Xamarin.Android project and add the Mono.Android.Export.dll to get it works.

Now rebuild the project and you will see the user data in the DetailActivity.

Congrats ! Now you know how to use Parcelables in your Xamarin.Android projects !

You will find all the source code in the final branch of the Github repository.

Happy codding !

You liked this tutorial ? Leave a star in the associated Github repository !

Do not hesitate to follow me on to not miss my next tutorial!