Android对象序列化

来源:互联网 发布:mysql 集群 phxsql 编辑:程序博客网 时间:2024/06/05 09:10

1、什么是对象序列化


  我们知道字符串信息可以通过IO流实现数据到本地磁盘的持久化或者通过网络进行数据传输,而所有的基本数据类型都可以转换为字符串,所以说基本数据类型也具备这些功能;而对象作为数据的一种集合体,是否也能实现同样的功能,一个在堆中创建的对象可以存储到本地磁盘文件中或者传输给网络中某个客户端,并且可以通过某种方式把它再恢复为对象,这就是Java中关于序列化的作用:把对象持久化到存储设备上或者通过网络进行传输。

  在Android中对象序列化的另一个目的就是完成对象在进程间的传递,另外序列化后的对象可以通过Intent进行组件之间的传递。


2、序列化的方式

  Java提供的方式:实现Serializable接口,它是空接口,也是一个标识接口,实现该接口对象,无需任何操作,Java会自动完成序列化的过程;大致的原理就是把对象的类名和可序列化的成员变量等信息转换为IO流进行本地存储或者传输,然后通过反射原理,根据构造函数(根据类名获取)、变量值反序列化为一个该类实例。

  Android提供的方式:实现Parcelable接口,该接口中方法会提供一个Parcel(包裹)对象,可以把指定成员变量写入到该容器中,反序列化时,可以通过该Parcel对象按照存储的顺序读取这些成员变量,并且通过被序列化类的构造函数创建并返回一个实例。


3、Serializable接口与Parcelable接口的区别

  1)Serializable实现,只需要implements Serializable接口即可,这是给对象打上一个标记,系统会自动将其序列化,这个过程不可见的。

  2)Parcelable实现,不仅需要implements Parcelable接口,还需要复写其中方法,包括复写内容接口描述方法,通过Parcel对象写入成员变量、通过Parcel对象写出成员变量,并且返回一个实例对象等。


  Parcelable并没有通过反射机制进行反序列化,而是通过Parcel容器进行写入和写出的方式,所以它的运行效率非常高,但是它不能把数据存储到磁盘文件中,所以如果是在内存中进对象的传输,为了追求效率,我们实现Parcelable接口,而如果是需要把对象持久化到磁盘文件中,实现Serializable接口。


4、Parcelable介绍


Google API关于Parcelable的描述,见Parcelable:

Interface for classes whose instances can be written to and restored from a Parcel. Classes implementing the Parcelable interface must also have a non-null static field called CREATOR of a type that implements the Parcelable.Creator interface


部分源码:

public interface Parcelable {    //内容描述接口,一般都是返回0    public int describeContents();    //通过Parcel对象写入    public void writeToParcel(Parcel dest, int flags);        public interface Creator<T>     {
  //通过Parcel对象写出           public T createFromParcel(Parcel source);           public T[] newArray(int size);    }}


5、实现Parcelable的步骤


1)通过 implements Parcelable 实现接口

2)重写 writeToParcel() 方法,通过Parcel对象的 wirteXXX()方法写入数据(XXX表示数据类型,比如int、String等),将对象中的成员变量打包到Parcel容器中,以便于从Parcel中获取数据。

3)重写describeContents()方法,内容描述功能,一般默认返回0即可,仅当当前对象中存在文件描述符时,此对象返回1.

4)提供一个名为CREATOR的常量,该常量的名称不能修改,类型为接口Parcelable.Creator<T>,泛型指定为被序列化的类,并且提供该接口类型的实例,需要复写接口中两个方法:createFromParcel(parcel in),该方法实现从Parcel中获取打包的数据,并封装为被序列化的类对象,然后返回;而newArray(int size)只需要返回一个类型为T,长度为size的数组,即 return new T[size],供外部类反序列化本来数组使用。


简而言之:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,在通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,因此写的顺序和读的顺序必须一致。


6、代码示例

package com.example.myapplication;import android.os.Parcel;import android.os.Parcelable;public class Person 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;    }    Person(){}    protected Person(Parcel in) {        name = in.readString();        age = in.readInt();    }    @Override    public int describeContents() {        //2.内容描述,一般返回0        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        //1、序列化:通过Parcel容器写入成员变量值        dest.writeString(name);        dest.writeInt(age);    }    public static final Creator<Person> CREATOR = new Creator<Person>() {        @Override        public Person createFromParcel(Parcel in) {            //3、通过Person构造函数接收一个Parcel对象,Parcel写出数据并进行对应赋值,建构一个Person对象            return new Person(in);        }        @Override        public Person[] newArray(int size) {            return new Person[size];        }    };}


package com.example.myapplication;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;public class MainActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(MainActivity.this,SecondActivity.class);                Person person = new Person();                person.setName("noodles");                person.setAge(18);                intent.putExtra("data",person);                startActivity(intent);            }        });    }}
package com.example.myapplication;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.widget.TextView;public class SecondActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.second_activity);        Intent intent = getIntent();        Person person =  intent.getParcelableExtra("data");        String msg = person.getName() + ":" + person.getAge();        TextView textView = (TextView) findViewById(R.id.text_view);        textView.setText(msg);    }}

结果:


参考:

1、http://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html

2、http://www.jianshu.com/p/a60b609ec7e7

3、第一行代码

4、Android开发艺术探索

0 0
原创粉丝点击