Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Utility class for dealing with Parcelables. Handles null checks for objects, and parcels some common non-Parcelable classes
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.os.Parcel;
import android.os.Parcelable;
public class ParcelableUtils {
public static void write(Parcel dest, String string) {
dest.writeByte((byte) (string == null ? 0 : 1));
if (string != null) {
dest.writeString(string);
}
}
public static String readString(Parcel source) {
if (source.readByte() == 1) {
return source.readString();
}
return null;
}
public static void write(Parcel dest, Parcelable parcelable, int flags) {
dest.writeByte((byte) (parcelable == null ? 0 : 1));
if (parcelable != null) {
dest.writeParcelable(parcelable, flags);
}
}
public static <T extends Parcelable> T readParcelable(Parcel source) {
if (source.readByte() == 1) {
return source.readParcelable(null);
}
return null;
}
public static void write(Parcel dest, Map<String, String> strings) {
if (strings == null) {
dest.writeInt(-1);
}
{
dest.writeInt(strings.keySet().size());
for (String key : strings.keySet()) {
dest.writeString(key);
dest.writeString(strings.get(key));
}
}
}
public static Map<String, String> readStringMap(Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
String value = source.readString();
map.put(key, value);
}
return map;
}
public static <T extends Parcelable> void write(Parcel dest,
Map<String, T> objects, int flags) {
if (objects == null) {
dest.writeInt(-1);
} else {
dest.writeInt(objects.keySet().size());
for (String key : objects.keySet()) {
dest.writeString(key);
dest.writeParcelable(objects.get(key), flags);
}
}
}
public static <T extends Parcelable> Map<String, T> readParcelableMap(
Parcel source) {
int numKeys = source.readInt();
if (numKeys == -1) {
return null;
}
HashMap<String, T> map = new HashMap<String, T>();
for (int i = 0; i < numKeys; i++) {
String key = source.readString();
T value = source.readParcelable(null);
map.put(key, value);
}
return map;
}
public static void write(Parcel dest, URL url) {
dest.writeString(url.toExternalForm());
}
public static URL readURL(Parcel source) {
try {
return new URL(source.readString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
public static void write(Parcel dest, Date date) {
dest.writeByte((byte) (date == null ? 0 : 1));
if (date != null) {
dest.writeLong(date.getTime());
}
}
public static Date readDate(Parcel source) {
if (source.readByte() == 1) {
return new Date(source.readLong());
}
return null;
}
public static <T extends Enum<T>> void write(Parcel dest, Enum<T> enu) {
if (enu == null) {
dest.writeString("");
} else {
dest.writeString(enu.name());
}
}
public static <T extends Enum<T>> T readEnum(Parcel dest, Class<T> clazz) {
String name = dest.readString();
if ("".equals(name)) {
return null;
}
return Enum.valueOf(clazz, name);
}
public static void write(Parcel dest, boolean bool) {
dest.writeByte((byte) (bool ? 1 : 0));
}
public static boolean readBoolean(Parcel source) {
return source.readByte() == 1;
}
public static <T extends Parcelable> void write(Parcel dest,
List<T> fields, int flags) {
if (fields == null) {
dest.writeInt(-1);
} else {
dest.writeInt(fields.size());
for (T field : fields) {
dest.writeParcelable(field, flags);
}
}
}
@SuppressWarnings("unchecked")
public static <T extends Parcelable> List<T> readParcelableList(
Parcel source) {
int size = source.readInt();
if (size == -1) {
return null;
}
ArrayList<T> list = new ArrayList<T>();
for (int i = 0; i < size; i++) {
list.add((T) source.readParcelable(null));
}
return list;
}
}
@diegum

This comment has been minimized.

Copy link

diegum commented Jun 22, 2015

Thanks for sharing this wisdom, @keyboardr!!

May I suggest an improvement?

In lines 36, 90 and 168 in which you call

   Parcel.readParcelable(null)

You can substitute null with

   Parcel.readParcelable(Thread.currentThread().getContextClassLoader())

Otherwise, you may get ClassNotFoundException in certain Android implementations (in particular, it was happening to me running Lollipop 5.1.1). Take a look to this thread for further info.

Let me know your thoughts about it.

@jayjaykim

This comment has been minimized.

Copy link

jayjaykim commented Oct 15, 2015

Brilliant!!!!

@sebastiencouture

This comment has been minimized.

Copy link

sebastiencouture commented Apr 28, 2016

Thread.currentThread().getContextClassLoader() is not guaranteed to work. It will work on most devices, but on some such as Samsung S3/S4 running Android 4.X/5.X it will still fail with ClassNotFoundException.

Instead use the class loader of the class being read.

@escobar5

This comment has been minimized.

Copy link

escobar5 commented May 14, 2016

I was having serious problems with Parcelables and this helped me a lot.

The only change was I did it was the one @diegum and @sebastiencouture suggested.

Thanks

@krllus

This comment has been minimized.

Copy link

krllus commented Sep 10, 2016

using null as parameter for readParcelable(null) causes an error for me. I replaced the signature of the methods that use this method to include the "ClassLoader creator", and now it seems to be solved.. also check if there are an 'else' statement missing in the line 44 45.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.