您的位置:首页 > 移动开发 > Android开发

Android序列化之Parcel

2015-09-16 22:52 344 查看

序列化方法

在Android系统中关于序列化的方法一般有两种,分别是实现Serializable接口和Parcelable接口,其中Serializable接口是来自Java中的序列化接口,而Parcelable是Android自带的序列化接口。

上述的两种序列化接口都有各自不同的优缺点,我们在实际使用时需根据不同情况而定。

Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC,而相比之下Parcelable的性能更高(毕竟是Android自带的),所以当在使用内存时(如:序列化对象在网络中传递对象或序列化在进程间传递对象),更推荐使用Parcelable接口。

但Parcelable有个明显的缺点:不能使用在要将数据存储在磁盘上的情况(如:永久性保存对象,保存对象的字节序列到本地文件中),因为Parcel本质上为了更好的实现对象在IPC间传递,并不是一个通用的序列化机制,当改变任何Parcel中数据的底层实现都可能导致之前的数据不可读取,所以此时还是建议使用Serializable 。

实现Parcelable接口主要有以下几步:

1)implements Parcelable。

2)重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从Parcel容器获取数据。

3)重写describeContents方法,内容接口描述,默认返回0即可。

4)实例化静态内部对象CREATOR实现接口Parcelable.Creator 。

下面以一个例子说明:

MainActivity中启动OtherActivity,并将一个对象传过去,这个时候我们就需要对该类实现序列化

package com.test.parcel;

import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;

public class StudentInfo implements Parcelable {

public static final String TAG = "MyParcel";

private String name;
private int age;

private StudentInfo(){

}

public StudentInfo(String name, int age){
Log.i(TAG, "StudentInfo construction");
this.name = name;
this.age = age;
}

public String toString(){
return "name: " + name + ", age:" + age;
}

@Override
public int describeContents() {
// 默认返回0就可以了
Log.i(TAG, "describeContents()");
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
// 写数据的操作
dest.writeString(name);
dest.writeInt(age);
Log.i(TAG, "writeToParcel()");

}

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) {
// 读数据,生成一个新对象,注意顺序跟写的顺序必须一致
StudentInfo stu = new StudentInfo();
stu.name = source.readString();
stu.age = source.readInt();
Log.i(TAG, "Parcelable.Creator createFromParcel()");
return stu;
}
};

}


我们在MainActivity中创建对象,通过Intent将该对象传给OtherActivity

package com.test.parcel;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity implements View.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.activity_main);
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
4000
(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn:
Intent intent = new Intent(this, OtherActivity.class);
Log.i(StudentInfo.TAG, "intent putExtra()");
//若只想传一个对象,则直接调用putExtra(String name, Parcelable value)这个方法即可
//注意这里传的是List,但是该list容器的对象实现了序列化接口,下面这两种调用方法都可以

//intent.putExtra("students", list);
intent.putParcelableArrayListExtra("students", list);
startActivity(intent);
break;
default:
break;
}

}
}


另一个Activity读取数据,生产新对象

package com.test.parcel;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;

public class OtherActivity extends Activity {

private ArrayList<StudentInfo> list;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);

list = getIntent().getParcelableArrayListExtra("students");
Iterator<StudentInfo> iter = list.iterator();
while(iter.hasNext()){
StudentInfo st = iter.next();
Log.i(StudentInfo.TAG, st.toString());
}
}

}


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

运行的LOG信息如下:

I/MyParcel( 1268): StudentInfo construction
I/MyParcel( 1268): StudentInfo construction
I/MyParcel( 1268): StudentInfo construction
I/MyParcel( 1268): intent putExtra()
I/MyParcel( 1268): writeToParcel()
I/MyParcel( 1268): writeToParcel()
I/MyParcel( 1268): writeToParcel()
I/MyParcel( 1268): Parcelable.Creator createFromParcel()
I/MyParcel( 1268): Parcelable.Creator createFromParcel()
I/MyParcel( 1268): Parcelable.Creator createFromParcel()
I/MyParcel( 1268): name: scott, age:23
I/MyParcel( 1268): name: zhangsan, age:18
I/MyParcel( 1268): name: lishi, age:20
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 数据传递