Android中的序列化

在编程中只要提到对象的序列化,我想大多数做过开发的同胞都会想到Serializable这个接口,这是JavaSE中支持的一种对象序列化方式,在Android中提供了另外一个对象序列化的接口,那就是今天我想阐述的重点内容Parcelable。


序列化的原因:

1.可以永久性的保持对象到本地磁盘中

2.作为数据流通过网络进行传输

3.可以实现进程之间的通讯


一 、Serializable接口

Serializable接口它没有任何方法和属性的接口,就是一个标识的作用,表示实现了该接口的对象可以进行序列化。


二、Parcelable接口 

Parcelabe接口是Android特有的接口,实现这个接口要比Serializable接口复杂一些,该接口需要实现writeToParcel()和describeContents()方法,还要实例化静态内部对象CREATOR实现接口Parcelabe.Creator。


三、Parcelabe和Serializable的作用、效率、区别和选择

1、作用:

Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以便数据传输,当然这种传输可能是程序内部的也可以是两个不同程序之间的。而Android提供的Parcelable的设计初衷是因为Serializable效率太慢,为了让Android程序内的不同组件之间以及不同Android程序之间高效的传输数据而设计,这些数据仅存在于内存中。Parcelable是通过IBinder通信的消息载体。

2、效率及其选择:

Parcelable的性能比Serializable好,在内存开销方面小,所以在内存之间传输数据时推荐使用Parcelable,比如Activity之间传输数据,而Serializable可以将数据持久化方便保存,所以在需要保存或网络传输时应该选择Serializable,因为Android不同版本的Parcelable有可能不同,所以不推荐使用Parcelable进行数据持久化。


四、演示Demo

package com.test.mode;

import android.os.Parcel;
import android.os.Parcelable;

public class StudentInfo implements Parcelable {

	private String name;
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public int describeContents() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		// TODO Auto-generated method stub
		dest.writeString(name);
		dest.writeInt(age);

	}

	public static final Parcelable.Creator<StudentInfo> CREATOR = new Creator<StudentInfo>() {

		@Override
		public StudentInfo[] newArray(int size) {
			// TODO Auto-generated method stub
			return new StudentInfo[size];
		}

		@Override
		public StudentInfo createFromParcel(Parcel source) {
			// TODO Auto-generated method stub
			StudentInfo stu = new StudentInfo();
			stu.name = source.readString();
			stu.age = source.readInt();

			return stu;
		}
	};

}

注意:实例化静态内部对象CREATOR实现接口Parcelabe.Creator时,必须用public static final 进行修饰,并且CREATOR只能为这个名字,不能更改,并且名字必须大写。

实现CREATOR对象中的createFromParcel()和newArray()方法,将Parcel对象反序列化成你定义的对象。


如下Demo演示了从OneActivity界面向TwoActivity界面传递一个ArrayList集合,然后在TwoActivity中打印出获取到的集合数据。


OneActivity代码:

public class OneActivity extends Activity implements OnClickListener {

	private ArrayList<StudentInfo> list;
	private Button btn;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.one);
		btn = (Button) findViewById(R.id.btn);
		btn.setOnClickListener(this);
		list = getData();

	}

	private ArrayList<StudentInfo> getData() {

		ArrayList<StudentInfo> list = new ArrayList<StudentInfo>();
		StudentInfo stu1 = new StudentInfo("scott", 23);
		StudentInfo stu2 = new StudentInfo("zhangsan", 18);
		StudentInfo stu3 = new StudentInfo("lishi", 20);
		list.add(stu1);
		list.add(stu2);
		list.add(stu3);
		return list;
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.btn:
			Intent intent = new Intent(this, TwoActivity.class);
			System.out.println("-----点击了btn");
			intent.putExtra("students", list);
			startActivity(intent);
			break;
		default:
			break;
		}

	}

}


TwoActivity代码:

public class TwoActivity extends Activity {

	private ArrayList<StudentInfo> list;

	private TextView tv_show;
	private StringBuffer sb = new StringBuffer();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.two);
		tv_show = (TextView) findViewById(R.id.tv_show);
		System.out.println("执行了OneActivity的onCreate()方法!");
		list = getIntent().getParcelableArrayListExtra("students");
		for (int i = 0; i < list.size(); i++) {
			sb.append(list.get(i).toString() + "\n");
			System.out.println("student=" + list.get(i).toString());
		}
		tv_show.setText(sb.toString());
	}

}


日志打印结果: 

04-02 19:35:24.671: I/System.out(10549): -----点击了btn
04-02 19:35:24.671: I/System.out(10549): 执行了Parcelable接口的writeToParcel()方法!
04-02 19:35:24.672: I/System.out(10549): 执行了Parcelable接口的writeToParcel()方法!
04-02 19:35:24.672: I/System.out(10549): 执行了Parcelable接口的writeToParcel()方法!
04-02 19:35:24.842: I/System.out(10549): 执行了OneActivity的onCreate()方法!
04-02 19:35:24.843: I/System.out(10549): 执行了CREATOR对象中的createFromParcel()方法,stu=StudentInfo [name=scott, age=23]
04-02 19:35:24.843: I/System.out(10549): 执行了CREATOR对象中的createFromParcel()方法,stu=StudentInfo [name=zhangsan, age=18]
04-02 19:35:24.843: I/System.out(10549): 执行了CREATOR对象中的createFromParcel()方法,stu=StudentInfo [name=lishi, age=20]
04-02 19:35:24.843: I/System.out(10549): student=StudentInfo [name=scott, age=23]
04-02 19:35:24.843: I/System.out(10549): student=StudentInfo [name=zhangsan, age=18]
04-02 19:35:24.844: I/System.out(10549): student=StudentInfo [name=lishi, age=20]


根据打印的日子可以看出,当执行putExtra()方法的时候,系统会自动调用Parcelable接口的writeToParcel()方法将数据写入内存或磁盘中,这就是Android中的序列化。当程序执行 getIntent().getParcelableArrayListExtra("students")方法的时候,系统会调用CREATOR对象中的createFromParcel()方法,将序列化到内存或磁盘中的数据反序列化成对象。其实 createFromParcel(Parcel source) 方法的形参source和Parcelable中writeToParcel(Parcel dest, int flags)方法的形参dest是同一个对象。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值