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::[email protected]");
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}.
*/
@Override
public 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.
*/
@Override
public ParcelableCartoon createFromParcel(Parcel source) {
Log.i(MSG, "ParcelableCartoon::Parcelable.Creator::createFromParcel");
return new ParcelableCartoon(source);
}@Override
public ParcelableCartoon[] newArray(int size) {
Log.i(MSG, "ParcelableCartoon::Parcelable.Creator::newArray");
return new ParcelableCartoon[size];
}};
public ParcelableCartoon(Parcel in){
Log.i(MSG, "ParcelableCartoon::[email protected]");
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;
}@Override
public 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;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sendData = (Button)this.findViewById(R.id.button1);
sendData.setOnClickListener(new OnClickListener(){@Override
public 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;@Override
protected 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的运行方式以及顺序。