Je trouve que Parcelable est le plus souvent utilisé dans Android dans les données Bu ndles, mais plus spécifiquement dans un gestionnaire qui envoie et reçoit des messages. Par exemple, vous pouvez avoir un AsyncTask
ou un Runnable
qui doit s'exécuter en arrière-plan, mais afficher les données résultantes dans le thread principal ou Activity
.
Voici un exemple simple. Si j'ai un Runnable
qui ressemble à ceci:
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);
// Deserialize HTTP response to concrete type.
ProductInfo info = GSON.fromJson(isr, PRODUCTINFO.getType());
Message msg = new Message();
Bundle b = new Bundle();
b.putParcelable(KEY, info);
msg.setData(b);
handler.sendMessage(msg);
}
catch (Exception err)
{
Log.e(TAG, err.toString());
}
}
}
Comme vous pouvez le voir, ce runnable prend un gestionnaire dans son constructeur. On appelle cela de quelque Activity
comme ceci:
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);
// use the data from the Parcelable 'ProductInfo' class here
}
}
}
private MyInnerHandler myHandler = new MyInnerHandler(this);
@Override
public void onClick(View v) {
AsyncRunnableExample thread = new AsyncRunnableExample(myHandler, barcode.getText().toString());
thread.start();
}
Maintenant, tout ce qui reste est le cœur de cette question, comment vous définissez une classe comme Parcelable
. J'ai choisi une classe assez complexe à montrer parce qu'il y a des choses que vous ne verriez pas avec une simple.Voici la classe ProductInfo
, qui unParcels proprement et Parcels:
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;
}
}
Le CREATOR
est critique, comme le constructeur résultant prendre une parcelle. J'ai inclus les types de données les plus complexes afin que vous puissiez voir comment Arrays Parcel et unParcel d'objets Parcelable. C'est une chose courante en utilisant Gson pour convertir JSON en objets avec des enfants comme dans cet exemple.
vous venez d'enregistrer ma journée. MERCI. – Matthias
Juste ne pas essayer cela avec Bitmaps à l'intérieur de votre colis (capacité) :( –
setDataPosition (0) m'a sauvé! Merci;) –