Android中的序列化浅析
序列化原因
序列化的原因基本可以归纳为以下三种情况:
1.永久性保存对象,保存对象的字节序列到本地文件中;
2.对象在网络中传递;
3.对象在ipc间传递。
序列化方法
在android系统中关于序列化的方法一般有两种,分别是实现serializable接口和parcelable接口,其中serializable接口是来自java中的序列化接口,而parcelable是android自带的序列化接口。
上述的两种序列化接口都有各自不同的优缺点,我们在实际使用时需根据不同情况而定。
1.serializable在序列化的时候会产生大量的临时变量,从而引起频繁的gc,而相比之下parcelable的性能更高(毕竟是android自带的),所以当在使用内存时(如:序列化对象在网络中传递对象或序列化在进程间传递对象),更推荐使用parcelable接口。
2.但parcelable有个明显的缺点:不能能使用在要将数据存储在磁盘上的情况(如:永久性保存对象,保存对象的字节序列到本地文件中),因为parcel本质上为了更好的实现对象在ipc间传递,并不是一个通用的序列化机制,当改变任何parcel中数据的底层实现都可能导致之前的数据不可读取,所以此时还是建议使用serializable 。
代码实现
serializable接口的实现及使用
serializable的接口实现很简单,只需让需要序列化的类继承serializable 即可,系统会自动将其序列化,具体代码如下:
public class book implements serializable { private static final long serialversionuid = 21455356667888l; private string mname; private string mprice; public string getmname() { return mname; } public void setmname(string mname) { this.mname = mname; } public string getmprice() { return mprice; } public void setmprice(string mprice) { this.mprice = mprice; } }
在activity中使用方法:
// serializable对象传递方法 public void setserializablemethod() { book book = new book(); book.setmname("王海康"); book.setmprice("20$"); intent intent = new intent(this, booktest.class); bundle bundle = new bundle(); bundle.putserializable(ser_key, book); intent.putextras(bundle); startactivity(intent); } // serializable对象获取方法 public book getserializablemethod(){ book mbook = (book )getintent().getserializableextra(ser_key); return mbook; }
parcelable接口的实现及使用
实现parcelable接口主要可以分为一下几步:
1)implements parcelable。
2)重写writetoparcel方法,将你的对象序列化为一个parcel对象,即:将类的数据写入外部提供的parcel中,打包需要传递的数据到parcel容器保存,以便从parcel容器获取数据。
3)重写describecontents方法,内容接口描述,默认返回0即可。
4)实例化静态内部对象creator实现接口parcelable.creator 。
注意:若将parcel看成是一个流,则先通过writetoparcel把对象写到流里面,再通过createfromparcel从流里读取对象,因此类实现的写入顺序和读出顺序必须一致。
具体实现代码如下:
public class person implements parcelable { private string mname; private string msex; private int mage; public string getmname() { return mname; } public void setmname(string mname) { this.mname = mname; } public string getmsex() { return msex; } public void setmsex(string msex) { this.msex = msex; } public int getmage() { return mage; } public void setmage(int mage) { this.mage = mage; } @override public int describecontents() { return 0; } @override public void writetoparcel(parcel dest, int flags) { dest.writestring(mname); dest.writestring(msex); dest.writeint(mage); } public static final parcelable.creator<person> creator = new creator<person>() { @override public person createfromparcel(parcel source) { person person = new person(); person.mname = source.readstring(); person.msex = source.readstring(); person.mage = source.readint(); return person; } //供反序列化本类数组时调用的 @override public person[] newarray(int size) { return new person[size]; } };
在activity中使用方法:
1)传递单一对象,具体代码如下:
// parcelable对象传递方法 public void setparcelablemethod() { person person = new person(); person.setmname("王海康"); person.setmsex("男"); person.setmage(45); intent intent = new intent(this, persontest.class); bundle bundle = new bundle(); bundle.putparcelable(par_key, person); intent.putextras(bundle); startactivity(intent); } // parcelable对象获取方法 public person getparcelablemethod(){ person mperson = (person)getintent().getparcelableextra(par_key); return mperson; }
2)传递对象列表,具体代码如下:
需要注意的是,若list personlist = new arraylist();则会报错,因为下面调用的putparcelablearraylist()函数其中一个参数的类型为arraylist。
// parcelable对象list传递方法 public void setparcelablelistmethod() { arraylist<person> personlist = new arraylist<person>(); person person1 = new person(); person1.setmname("王海康"); person1.setmsex("男"); person1.setmage(45); personlist.add(person1); person person2 = new person(); person2.setmname("薛岳"); person2.setmsex("男"); person2.setmage(15); personlist.add(person2); intent intent = new intent(this, persontest.class); bundle bundle = new bundle(); bundle.putparcelablearraylist(par_list_key, personlist); intent.putextras(bundle); startactivity(intent); } // parcelable对象获取方法 public arraylist<person> getparcelablemethod(){ arraylist<person> mpersonlist = getintent().getparcelableextra(par_list_key); return mpersonlist; }
3)最后介绍一个投机取巧的方法:
不用继承parcelable或serializable方法即可实现ipc中对象的传递。这种方法的实现原理不是很明白,只知道代码中new arraylist()返回的其实是一个emptyarray.object数组,不过我感觉应该还是系统调用serializable进行序列化的,如果各位读者有好的想法,欢迎告知。
具体代码如下:
//对象list传递 public void setobjectmethod(){ ......(省略) arraylist list = new arraylist(); //objectlist为某一对象列表 list.add(objectlist); bundle.putparcelablearraylist(par_list_key, list); intent.putextras(bundle); startactivity(intent); } //获取对象list arraylist list = bundle.getparcelablearraylist("list"); //强转成你自己定义的list,这样objectlist就是你传过来的那个list了。 objectlist= (list<object>) list.get(0);
推荐阅读
-
MySQL查询中LIMIT的大offset导致性能低下浅析
-
浅析Java中Apache BeanUtils和Spring BeanUtils的用法
-
PHP5.0中多态性的实现方案浅析
-
PHP中SERIALIZE和JSON序列化与反序列化的区别
-
深入浅析js中的正则表达式
-
浅析CSS3 中的 transition,transform,translate之间区别和作用
-
PHP中的命名空间相关概念浅析
-
辛星浅析php变量中的优先级问题
-
Android App中DrawerLayout抽屉效果的菜单编写实例,drawerlayout上下抽屉_PHP教程
-
android教程之把自己的应用加入到系统分享中