如果都了解过Parcel类的实现,那么其基本只序列化基本类型的特性还不能满足我们的需求(事实上android中Binder的IPC通信中,Parcel对象也能传递Parcel对象,现实编程用得极少)。具体的Parcel类这里不做介绍。点击查看Parcel类详解
Serializable和Parcelable在现实中的应用场景,有个网友写得非常nice,强烈推荐大家有空看下。点击查看Serializable和Parcelable你应该懂得的几个应用场景
之前学习java的时候,实现Serializable接口序列化一个对象并通过IO操作就可以保存在本地存储区中。而Parcelable的用法并不是如此。两者间虽然都支持序列化、反序列操作,但是其存储的媒介截然不同。前者一般是通过IO流写入本地硬盘文件中而Parcelable则在写入内存。运行在android手机上的应用追求运行速度更快。假设在同一进程的不同ActivityA和B之前传递一个对象,如果还需要先把A对象写入SD卡,然后B对象再从SD卡读到内存中,那么做了很多功夫。Adnroid提供Parcelable接口直接操作内存中的序列化对象,写入和读取速度明显大于IO操作,因此性能也有所提升。故Android实现序列化对象优先选择“Parcelable”。
基于上述内容的认知,下面给出Android现实编程的例子:分别用两种序列化方式对具体对象进行序列化,并在不同的Activity中传递。
MainActiviy代码
package com.example.androidtest_parcelable;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button ac1,ac2;
private Intent intent;
private PersonByParcelable p;
private PersonBySerializable s;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initListener();
initData();
}
public void initView(){
ac1 = (Button)findViewById(R.id.ac1);
ac2 = (Button)findViewById(R.id.ac2);
}
public void initListener(){
ac1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
intent = new Intent(MainActivity.this, ActivityA.class);
Bundle b = new Bundle();
b.putParcelable("parcelable", p);
intent.putExtras(b);
startActivity(intent);
}
});
ac2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
intent = new Intent(MainActivity.this, ActivityB.class);
Bundle b = new Bundle();
b.putSerializable("serializable", s);
intent.putExtras(b);
startActivity(intent);
}
});
}
public void initData(){
p = new PersonByParcelable();
p.setName("parcelable");
p.setAge(1);
p.setAddress("我来自ParsonByParcelable");
s = new PersonBySerializable();
s.setName("serializable");
s.setAge(2);
s.setAddress("我来自PersonBySerializable");
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
ActivityA代码,用于显示反序列化
Parcelable序列化的对象。
package com.example.androidtest_parcelable;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class ActivityA extends Activity{
private TextView mTextView;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ac1);
initView();
}
public void initView(){
intent = getIntent();
Bundle b = intent.getExtras();
PersonByParcelable p = (PersonByParcelable)b.getParcelable("parcelable");
mTextView = (TextView)findViewById(R.id.mTextView);
mTextView.setText("name:"+p.getName()+'\n'
+"age:"+p.getAge()+"\n"
+"address:"+p.getAddress());
}
}
ActivityB代码,用于显示反序列化Serializable序列化的对象。
package com.example.androidtest_parcelable;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class ActivityB extends Activity{
private TextView mTextView;
private Intent intent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ac2);
initView();
}
public void initView(){
intent = getIntent();
Bundle b = intent.getExtras();
PersonBySerializable s = (PersonBySerializable) b.getSerializable("serializable");
mTextView = (TextView)findViewById(R.id.mTextView);
mTextView.setText("name:"+s.getName()+'\n'
+"age:"+s.getAge()+"\n"
+"address:"+s.getAddress());
}
}
分别对应的xml布局
MainActivity布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="welcome to yummlau's bolg"
android:textSize="20sp" />
<Button
android:id="@+id/ac1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="传递Parcelable对象" />
<Button
android:id="@+id/ac2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="传递Serializable对象" />
</LinearLayout>
ActivitA和ActivityB布局(是相同的)
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_marginTop="10dp"
android:id="@+id/mTextView"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:textSize="20sp"/>
</LinearLayout>
两个Bean类,分别用两种序列化手段
PersonByParcelable类,该类必须实现的的内容有:
1.无参构造器,用于产生类对象
2.有参构造器,用于反序列化后加载对象信息
3.writeToParcel(Parcel dest,int flags),此方法根据自己对象内容,分别按顺序写入dest包中,切记,这里与后面读取的顺序要一直。
4.describeContents(),此方法标志序列化内容,重写默认就可以了。
5.Parcelable.Creator<XXX>,此方法供系统内部存放序列化对象。
</pre></p><p><span style="font-family:SimHei;"></span><pre name="code" class="java" style="font-size:14px;">package com.example.androidtest_parcelable;
import android.os.Parcel;
import android.os.Parcelable;
public class PersonByParcelable implements Parcelable{
private String name;
private int age;
private String address;
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@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);
dest.writeString(address);
}
public static final Parcelable.Creator<PersonByParcelable> CREATOR = new Parcelable.Creator<PersonByParcelable>() {
public PersonByParcelable createFromParcel(Parcel in) {
return new PersonByParcelable(in);
}
public PersonByParcelable[] newArray(int size) {
return new PersonByParcelable[size];
}
};
public PersonByParcelable(){
}
public PersonByParcelable(Parcel in){
this.name = in.readString();
this.age = in.readInt();
this.address = in.readString();
}
}
PersonBySerializable类,该类必须实现的的内容有:
1.产生序列化ID
注意:该ID分为默认和随机,本demo因为有本地同个进程中实现并且序列化和反序列化都是用同个类,所以我取哪种方式都无所谓。然而如果是序列化和反序列分别在不同端的程序中,那么就应该保持ID的一致性才能正确反序列化对象。详情见开头的应用场景。
package com.example.androidtest_parcelable;
import java.io.Serializable;
public class PersonBySerializable implements Serializable{
/**
* 序列化ID,自动生成
*/
private static final long serialVersionUID = 996340687144383140L;
private String name;
private int age;
private String address;
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;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Demo图示
运行后界面
到此基本的传递对象演示完毕,如有错误欢迎指出。