I found that Parcelable is most often used in Android in data packets, but more specifically in a handler that sends and receives messages. For example, you may have AsyncTask or Runnable , which should run in the background, but send the received data to the main thread or Activity .
Here is a simple example. If I have a Runnable that looks like this:
package com.example; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import com.example.data.ProductInfo; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import com.squareup.okhttp.OkHttpClient; public class AsyncRunnableExample extends Thread { public static final String KEY = "AsyncRunnableExample_MSG_KEY"; private static final String TAG = AsyncRunnableExample.class.getSimpleName(); private static final TypeToken<ProductInfo> PRODUCTINFO = new TypeToken<ProductInfo>() { }; private static final Gson GSON = new Gson(); private String productCode; OkHttpClient client; Handler handler; public AsyncRunnableExample(Handler handler, String productCode) { this.handler = handler; this.productCode = productCode; client = new OkHttpClient(); } @Override public void run() { String url = "http://someserver/api/" + productCode; try { HttpURLConnection connection = client.open(new URL(url)); InputStream is = connection.getInputStream(); InputStreamReader isr = new InputStreamReader(is);
As you can see, this runnable accepts a handler in its constructor. This is called from some Activity as follows:
static class MyInnerHandler extends Handler{ WeakReference<MainActivity> mActivity; MyInnerHandler(MainActivity activity) { mActivity = new WeakReference<MainActivity>(activity); } @Override public void handleMessage(Message msg) { MainActivity theActivity = mActivity.get(); ProductInfo info = (ProductInfo) msg.getData().getParcelable(AsyncRunnableExample.KEY);
Now all that remains is the heart of this question, how do you define a class as Parcelable . I chose a rather complicated class to show, because there are some things that you would not see with a simple one. Here is the ProductInfo class, which is clean and unParcels clean:
public class ProductInfo implements Parcelable { private String brand; private Long id; private String name; private String description; private String slug; private String layout; private String large_image_url; private String render_image_url; private String small_image_url; private Double price; private String public_url; private ArrayList<ImageGroup> images; private ArrayList<ProductInfo> related; private Double saleprice; private String sizes; private String colours; private String header; private String footer; private Long productcode; // getters and setters omitted here @Override public void writeToParcel(Parcel dest, int flags) { dest.writeLong(id); dest.writeString(name); dest.writeString(description); dest.writeString(slug); dest.writeString(layout); dest.writeString(large_image_url); dest.writeString(render_image_url); dest.writeString(small_image_url); dest.writeDouble(price); dest.writeString(public_url); dest.writeParcelableArray((ImageGroup[])images.toArray(), flags); dest.writeParcelableArray((ProductInfo[])related.toArray(), flags); dest.writeDouble(saleprice); dest.writeString(sizes); dest.writeString(colours); dest.writeString(header); dest.writeString(footer); dest.writeLong(productcode); } public ProductInfo(Parcel in) { id = in.readLong(); name = in.readString(); description = in.readString(); slug = in.readString(); layout = in.readString(); large_image_url = in.readString(); render_image_url = in.readString(); small_image_url = in.readString(); price = in.readDouble(); public_url = in.readString(); images = in.readArrayList(ImageGroup.class.getClassLoader()); related = in.readArrayList(ProductInfo.class.getClassLoader()); saleprice = in.readDouble(); sizes = in.readString(); colours = in.readString(); header = in.readString(); footer = in.readString(); productcode = in.readLong(); } public static final Parcelable.Creator<ProductInfo> CREATOR = new Parcelable.Creator<ProductInfo>() { public ProductInfo createFromParcel(Parcel in) { return new ProductInfo(in); } public ProductInfo[] newArray(int size) { return new ProductInfo[size]; } }; @Override public int describeContents() { return 0; } }
CREATOR is critical, as is the resulting constructor that takes the parcel. I have included more complex data types so you can see how Parcel and UnParcel arrays are Parcelable arrays. This is a common thing when using Gson to convert JSON to objects with children, as in this example.
David S. Nov 19 '13 at 16:58 2013-11-19 16:58
source share