android中Parcelable和Serializable的使用

来源:互联网 发布:台球 知乎 编辑:程序博客网 时间:2024/05/16 06:44
Parcelable的用法:
android提供了一种新的类型:Parcel。本类被用作封装数据的容器,封装后的数据可以通过Intent或IPC传递。 除了基本类型以
外,只有实现了Parcelable接口的类才能被放入Parcel中。
Parcelable实现要点:需要实现三个东西
1)writeToParcel 方法。该方法将类的数据写入外部提供的Parcel中.声明如下:
writeToParcel (Parcel dest, int flags) 具体参数含义见javadoc
2)describeContents方法。没搞懂有什么用,反正直接返回0也可以
3)静态的Parcelable.Creator接口,本接口有两个方法:
createFromParcel(Parcel in) 实现从in中创建出类的实例的功能
newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话(return new T[size])即可。估计本方法是供外部类反序列化本类数组使用。
测试用的接收信息Activity
import android.app.Activity;   
 
import android.content.Intent;   
 
import android.os.Bundle;   
import android.os.Parcelable;   
  
public class Test extends Activity {   
      
    @Override  
    public void onCreate(Bundle savedInstanceState) {   
        super.onCreate(savedInstanceState);   
        setContentView(R.layout.main);   
        Intent i = getIntent();   
        Person p = i.getParcelableExtra("yes");   
        System.out.println("---->"+p.name);   
        System.out.println("---->"+p.map.size());   
    }   
}  
发送的Activity
import java.util.HashMap;   
  
import android.app.Activity;   
import android.content.Intent;   
import android.os.Bundle;   
  
public class TestNew extends Activity {   
      
    @Override  
    public void onCreate(Bundle savedInstanceState) {   
        super.onCreate(savedInstanceState);   
        setContentView(R.layout.main);   
        Intent intent = new Intent();   
        Person p = new Person();   
        p.map = new HashMap<String,String>();   
        p.map.put("yes", "ido");   
        p.name="ok";   
        intent.putExtra("yes", p);   
        intent.setClass(this, Test.class);   
        startActivity(intent);   
    }   
}  
Parcelable的实现类
import java.util.HashMap;   
  
import android.os.Parcel;   
import android.os.Parcelable;   
  
public class Person implements Parcelable {   
  
    public HashMap<String,String> map = new HashMap<String,String> ();   
       
    public String name ;   
    @Override  
    public int describeContents() {   
        return 0;   
    }   
  
    @Override  
    public void writeToParcel(Parcel dest, int flags) {   
  
        dest.writeMap(map);   
        dest.writeString(name);   
    }   
    public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {   
//重写Creator
  
        @Override  
        public Person createFromParcel(Parcel source) {   
            Person p = new Person();   
            p.map=source.readHashMap(HashMap.class.getClassLoader());   
            p.name=source.readString();   
            return p;   
        }   
  
        @Override  
        public Person[] newArray(int size) {   
            // TODO Auto-generated method stub   
            return null;   
        }   
    };   

}   

实现java.io.Serializable 接口的类是可序列化的。没有实现此接口的类将不能使它们的任一状态被序列化或逆序列化。
  序列化类的所有子类本身都是可序列化的。这个序列化接口没有任何方法和域,仅用于标识序列化的语意。允许非序列化类的子类型序列化,子类型可以假定负责保存和恢复父类型的公有的、保护的和(如果可访问)包的域的状态。只要该类(扩展)有一个无参构造子,可初始化它的状态,那么子类型就可承担上述职责。在这种情况下申明一个可序列化的类是一个错误。此错误将在运行时被检测。就是可以把对象存到字节流,然后可以恢复!
  例如:Integer实现了Serializable,所以可以把一个Integer的对象用IO写到文件里,之后再可以从文件里读出,如你开始写入的时候那个对象的intValue() 是5的话,那读出来之后也是5。这一点体现了用序化类的作用,即用来传送类的对象。

  所谓的Serializable,就是java提供的通用数据保存和读取的接口。至于从什么地方读出来和保存到哪里去都被隐藏在函数参数的背后了。这样子,任何类型只要实现了Serializable接口,就可以被保存到文件中,或者作为数据流通过网络发送到别的地方。也可以用管道来传输到系统的其他程序中。这样子极大的简化了类的设计。只要设计一个保存一个读取功能就能解决上面说得所有问题。

Object serialization的定义:
Object serialization 允许你将实现了Serializable接口的对象转换为字节序列,这些字节序列可以被完全存储以备以后重新生成原来的对象。
serialization不但可以在本机做,而且可以经由网络操作(RMI)。这个好处是很大的----因为它自动屏蔽了操作系统的差异,字节顺序(用Unix下的c开发过网络编程的人应该知道这个概念)等。比如,在Window平台生成一个对象并序列化之,然后通过网络传到一台Unix机器上,然后可以在这台Unix机器上正确地重构这个对象。
Object serialization主要用来支持2种主要的特性:
1。Java的RMI(remote method invocation).RMI允许象在本机上一样操作远程机器上的对象。当发送消息给远程对象时,就需要用到serializaiton机制来发送参数和接收返回直
2。Java的JavaBeans. Bean的状态信息通常是在设计时配置的。Bean的状态信息必须被存起来,以便当程序运行时能恢复这些状态信息。这也需要serializaiton机制。
二。sakulagi和rollingpig说的持久化我也说一下。
我觉得你们说的应该是英文里的persistence.但是Java语言里现在只支持lightweight persistence,就是轻量级持久化,这是通过serialization机制来实现的。
persistence是指一个对象的生命周期不由程序是否执行来决定,即使是在程序终止时这个对象也存在。它把一个serializable的对象写到磁盘(本机或其他机器上的非RAM存储器),并在程序重新调用时再读取对象到通常的RAM存储器。
为什么说Java的serialization机制实现的是lightweight persistence?因为你必须显式的序列化和反序列化程序里的对象;而不是直接由一个关键词来定义一个对象是序列化的然后由系统做相应的处理。
下面是关于序列化的一个实例:
程序名称:SerializationDemo.java
程序主题:实现对象的序列化和反序列化
程序说明:该程序由实例化一个MyClass类的对象开始,该对象有三个实例变量,类型分别为String、int、double,是希望存储和恢复的信息。
代码内容

import java.io.*;

public class SerializationDemo{

          public static void main(String args[]){
//Object serialization
try{
MyClass object1=new MyClass("Hello",-7,2.7e10);
System.out.println("object1:"+object1);
FileOutputStream fos=new FileOutputStream("serial");
ObjectOutputStream oos=new ObjectOutputStream(fos);
oos.writeObject(object1);
oos.flush();
oos.close();
}
catch(Exception e){
System.out.println("Exception during serialization:"+e);
System.exit(0);
}

//Object deserialization
try{
MyClass object2;
FileInputStream fis=new FileInputStream("serial");
ObjectInputStream ois=new ObjectInputStream(fis);
object2=(MyClass)ois.readObject();
ois.close();
System.out.println("object2:"+object2);
}
catch(Exception e){
System.out.println("Exception during deserialization:"+e);
System.exit(0);

}
}
}

class MyClass implements Serializable{

String s;
int i;
double d;

public MyClass(String s,int i,double d){

    this.s=s;
    this.i=i;
    this.d=d;

}

public String toString(){
    return "s="+s+";i="+i+";d="+d;
}
}
程序运行结果:object1和object2的实例变量是一样的,输出如下:

object1:s=Hello;i=-7;d=2.7E10 object2:s=Hello;i=-7;d=2.7E10
Serializable 和 Parcelable 区别
android 中自定义的对象序列化的问题有两个选择一个是Parcelable,另外一个是Serializable。

一 序列化原因:

1.永久性保存对象,保存对象的字节序列到本地文件中;
2.通过序列化对象在网络中传递对象;
3.通过序列化在进程间传递对象。 

二 至于选取哪种可参考下面的原则:

1.在使用内存的时候,Parcelable 类比Serializable性能高,所以推荐使用Parcelable类。
2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3.Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点, 也不提倡用,但在这种情况下,还是建议你用Serializable 。

实现:
1 Serializable 的实现,只需要继承  implements Serializable 即可。这只是给对象打了一个标记,系统会自动将其序列化。

2 Parcelabel 的实现,需要在类中添加一个静态成员变量 CREATOR,这个变量需要继承 Parcelable.Creator 接口。
public class MyParcelable implements Parcelable {
     
private int mData;

     
public int describeContents() {
         
return 0;
     }

     
public void writeToParcel(Parcel out, int flags) {
         out.writeInt(mData);
     }

     
public static final Parcelable.Creator<MyParcelable> CREATOR
             
= new Parcelable.Creator<MyParcelable>() {
         
public MyParcelable createFromParcel(Parcel in) {
             
return new MyParcelable(in);
         }

         
public MyParcelable[] newArray(int size) {
             
return new MyParcelable[size];
         }
     };
     
     
private MyParcelable(Parcel in) {
         mData 
= in.readInt();
     }
 }


原创粉丝点击