Android – Interface Parcelable et tableaux

Android propose dans ses outils une interface très pratique Parcelable. Elle permet d’implémenter un système de sauvegarde des données d’objets lors de :

Cependant, il y a quelque chose qui n’est pas très documenté, c’est la gestion des tableaux au sein de ces objets Parcelable. En effet, il existe les méthodes readIntArray et writeIntArray pour les tableaux d’entiers mais leur utilisation n’est pas documentée et j’ai pu trouver pas mal de questions sur ce sujet en cherchant sur le net.
Cette article présente comment les utiliser.

Pour cela nous  allons partir de l’exemple fourni par la documentation d’Android et y ajouter un tableau que nous allons sauvegarder et restaurer à l’aide de l’objet Parcel :

public class MyParcelable implements Parcelable {
	public int mData;
	public int[] mArrayData = new int[0]; // tableau qui nous interresse

	public MyParcelable() {
		super();
	}

	public int describeContents() {
		return 0;
	}

	public void writeToParcel(Parcel out, int flags) {
		out.writeInt(mData);
	}

	public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
		public MyParcelable createFromParcel(Parcel in) {
			return new MyParcelable(in);
		}

		public MyParcelable[] newArray(int size) {
			return new MyParcelable[size];
		}
	};

	private MyParcelable(Parcel in) {
		mData = in.readInt();
	}
}

Pour cela nous allons utiliser les méthodes writeIntArray et readIntArray respectivement dans les méthodes writeToParcel(Parcel out, int flags) et le constructeur MyParcelable(Parcel in). Le problème c’est que contrairement à la méthode readInt, readIntArray ne nous retourne pas le résultat attendu (un tableau d’entier) mais celui est au contraire passé en paramètre. Le premier réflexe est d’écrire ceci :

	public void writeToParcel(Parcel out, int flags) {
		out.writeInt(mData);
		out.writeIntArray(mArrayData);
	}

	private MyParcelable(Parcel in) {
		mData = in.readInt();
		in.readIntArray(mArrayData);
	}

Ceci pose problème et on se retrouve l’exception suivante :

java.lang.RuntimeException: bad array lengths

Le soucis vient du fait qu’Android essaie d’écrire les données qu’il a sauvegardées dans le Parcel dans un tableau de taille 0, d’où l’exception. En fait, l’astuce est de fournir à la méthode readIntArray un tableau déjà initialisé avec la bonne taille. Mais comment connaître la taille d’un tableau que l’on a pas encore récupérer allez-vous me dire ? L’astuce est sauvegarder cette taille dans le Parcel 🙂 :

	public void writeToParcel(Parcel out, int flags) {
		out.writeInt(mData);
		out.writeInt(mArrayData.length);
		out.writeIntArray(mArrayData);
	}

	private MyParcelable(Parcel in) {
		mData = in.readInt();
		mArrayData = new int[in.readInt()];
		in.readIntArray(mArrayData);
	}

Et voilà le tour est joué. Cette exmple présente comment implémenter cela pour un tableau d’entiers mais ceci est applicable à beaucoup d’autres types (boolean, double, float, String, … et bien sûr Parcelable)

Publicités

Étiquettes : , , , , , , , , ,

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :