Parcelable使用的一个地方就是在进程间传递一个自定义的较为复杂的对象,对Parcelable学习了一下写下自己的观点。
将一个对象比如说一个名字为Cartoon的自定义类,由一个activity传递到另外一个activity去,这个时候就要用到Parcelable了。首先我们先构建一个bean。
package com.example.sendobjfromactivity.bean;import android.graphics.Bitmap;public class Cartoon {private Bitmap figure;private String name;private String creator;public Bitmap getFigure() {return figure;}public void setFigure(Bitmap figure) {this.figure = figure;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getCreator() {return creator;}public void setCreator(String creator) {this.creator = creator;} }
这就是我们要传输的数据的格式,下面就思考,要将其在线程间进行传输,就要对其实现序列化,在Android中也就是实现Parcelable接口,这个借口中需要我们实现的主要方法有writeToParcel,describe,ContentsParcelable.Creator<?>。完成完成序列化是依靠writeToParcel方法,而对对象进行反序列化并且返回一个对象实例的是依靠ContentsParcelable.Creator<?>。
下面来看这样一段代码,ParcelableCartoon类实现了Parcelable接口
package com.example.sendobjfromactivity.bean;import android.graphics.Bitmap; import android.os.Parcel; import android.os.Parcelable; import android.util.Log;public class ParcelableCartoon implements Parcelable {private Cartoon cartoon;private static final String MSG = "MESSAGE"; public ParcelableCartoon(Cartoon cartoon){Log.i(MSG, "ParcelableCartoon::ParcelableCartoon@Cartoon");this.cartoon = cartoon;}// 将对象写入Parcel容器中去// 完成对对象的序列化/*** Flatten this object in to a Parcel.* * @param dest The Parcel in which the object should be written.* @param flags Additional flags about how the object should be written.* May be 0 or {@link #PARCELABLE_WRITE_RETURN_VALUE}.*/@Overridepublic void writeToParcel(Parcel dest, int flags) {Log.i(MSG, "ParcelableCartoon::writeToParcel");dest.writeString(cartoon.getName());dest.writeString(cartoon.getCreator());dest.writeParcelable(cartoon.getFigure(), PARCELABLE_WRITE_RETURN_VALUE);}// 完成对序列化的对象反序列化public static final Parcelable.Creator<ParcelableCartoon> CREATOR = new Parcelable.Creator<ParcelableCartoon>(){// 从Parcel容器中获取序列化的对象,并将其反序列化,得到该对象的实例/*** Create a new instance of the Parcelable class, instantiating it* from the given Parcel whose data had previously been written by* {@link Parcelable#writeToParcel Parcelable.writeToParcel()}.* * @param source The Parcel to read the object's data from.* @return Returns a new instance of the Parcelable class.*/@Overridepublic ParcelableCartoon createFromParcel(Parcel source) {Log.i(MSG, "ParcelableCartoon::Parcelable.Creator::createFromParcel");return new ParcelableCartoon(source);}@Overridepublic ParcelableCartoon[] newArray(int size) {Log.i(MSG, "ParcelableCartoon::Parcelable.Creator::newArray");return new ParcelableCartoon[size];}};public ParcelableCartoon(Parcel in){Log.i(MSG, "ParcelableCartoon::ParcelableCartoon@Parcel");cartoon = new Cartoon();String name = in.readString();cartoon.setName(name);cartoon.setCreator(in.readString());cartoon.setFigure((Bitmap)in.readParcelable(Bitmap.class.getClassLoader()));}public Cartoon getCartoon() {Log.i(MSG, "ParcelableCartoon::getCartoon");return cartoon;}@Overridepublic int describeContents() {Log.i(MSG, "ParcelableCartoon::describeContents");return 0;} }
在该类中用英文的注释引用了Android文档中的注释。在该类中涉及到一个Parcel,它是一个容器,它的主要任务是对需要序列化的对象进行写入,对需要反序列化的对象进行写出(构造一个实例)。
完成了这些,就可以对对象进行序列化了,也就是说我们可以传递对象了。
下面完成俩个activity,一个负责发送数据,一个用来接收数据。
SendObjFromActivity.java完成发送
package com.example.sendobjfromactivity;import java.io.InputStream;import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;import com.example.sendobjfromactivity.bean.Cartoon; import com.example.sendobjfromactivity.bean.ParcelableCartoon;public class SendObjFromActivity extends Activity {private Button sendData;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);sendData = (Button)this.findViewById(R.id.button1);sendData.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {Cartoon cartoon = new Cartoon();cartoon.setName("Android");cartoon.setCreator("Google");InputStream is = getResources().openRawResource(R.drawable.ic_launcher);Bitmap bitmap = BitmapFactory.decodeStream(is);cartoon.setFigure(bitmap);Intent intent = new Intent(SendObjFromActivity.this, ReceiveObjActivity.class);// 完成对象的序列化操作ParcelableCartoon parcelableCartoon = new ParcelableCartoon(cartoon);intent.putExtra("msg", parcelableCartoon);startActivity(intent);}});} }
ReceiveObjActivity.java完成对数据的接收
package com.example.sendobjfromactivity;import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.widget.ImageView; import android.widget.TextView;import com.example.sendobjfromactivity.bean.Cartoon; import com.example.sendobjfromactivity.bean.ParcelableCartoon;public class ReceiveObjActivity extends Activity {private ImageView showImage;private TextView showText;@Overrideprotected void onCreate(Bundle savedInstanceState) {Log.i("MESSAGE", "进入到了另外的一个activity中去");super.onCreate(savedInstanceState);setContentView(R.layout.display_obj);showImage = (ImageView)this.findViewById(R.id.imageView1);showText = (TextView)this.findViewById(R.id.textView1);Intent intent = getIntent();ParcelableCartoon parcelableCartoon = (ParcelableCartoon) intent.getParcelableExtra("msg");Cartoon cartoon = parcelableCartoon.getCartoon();showImage.setImageBitmap(cartoon.getFigure());showText.setText(cartoon.getName()+"\n"+cartoon.getCreator());} }
在这个程序中会调用Parcelable.Creator<ParcelableCartoon>内的方法,来完成反序列化。
需要到两个xml布局文件:display_obj.xml,main.xml。比较简单不再叙述。
在AndroidManifest.xml中配置下activity。这样就完成了一个小的数据传输程序了,看下运行结果
在控制台中输出来的信息
这样可以看出来Parcelable的运行方式以及顺序。