Android中序列化
来源:互联网 发布:python sleep用法 编辑:程序博客网 时间:2024/05/22 22:47
(一)Serializable
Android应用是用java开发,那么java序列化Serializable也是可以使用的,java序列化优点是使用简洁,开销较大,适合用用于存取到设备上 如SD卡等。
把需要序列化数据类接入Serializable接口就可以了,如果有不想序列化的数据还可以用 transient 来取消这个变量的序列化。代码如下:
package com.xue.qin.demo.myserialization;import java.io.Serializable;/** * Created by xue.qin on 2017/6/5. */public class MyObject implements Serializable { private int n; private String name; transient String useless; public MyObject(int n, String name, String useless) { this.n = n; this.name = name; this.useless = useless; } @Override public String toString() { return "( n:" + n + " name:" + name + " useless:" + useless + " 地址:" + super.toString()+" )"; }}
MyObject obj1, obj2, obj3; MyObject obj4, obj5, obj6; try { obj2 = new MyObject(1, "dog","here"); obj1 = obj2; obj3 = new MyObject(2, "cat","there"); Log.i(TAG, "写入的对象\n"); Log.i(TAG, "obj1 = " + obj1 + " "); Log.i(TAG, "obj2 = " + obj2 + " "); Log.i(TAG, "obj3 = " + obj3 + " \n"); ByteArrayOutputStream buf = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(buf); out.writeObject(obj1); out.writeObject(obj2); out.writeObject(obj3); ByteArrayInputStream bufin = new ByteArrayInputStream(buf.toByteArray()); ObjectInputStream in = new ObjectInputStream(bufin); obj4 = (MyObject) in.readObject(); obj5 = (MyObject) in.readObject(); obj6 = (MyObject) in.readObject(); Log.i(TAG, "读取的对象\n"); Log.i(TAG, "obj4 = " + obj4 + " "); Log.i(TAG, "obj5 = " + obj5 + " "); Log.i(TAG, "obj6 = " + obj6 + " "); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); }
代码中obj1,和obj2 同时指向同一个引用,写入buffer,再读从buffer取出来,打印的log如下:
01-04 18:21:58.302 18984-18984/? I/ObjectNet: 写入的对象01-04 18:21:58.302 18984-18984/? I/ObjectNet: obj1 = ( n:1 name:dog useless:here 地址:com.xue.qin.demo.myserialization.MyObject@e3956d8 ) 01-04 18:21:58.302 18984-18984/? I/ObjectNet: obj2 = ( n:1 name:dog useless:here 地址:com.xue.qin.demo.myserialization.MyObject@e3956d8 ) 01-04 18:21:58.303 18984-18984/? I/ObjectNet: obj3 = ( n:2 name:cat useless:there 地址:com.xue.qin.demo.myserialization.MyObject@9effa31 ) 01-04 18:21:58.310 18984-18984/? I/ObjectNet: 读取的对象01-04 18:21:58.310 18984-18984/? I/ObjectNet: obj4 = ( n:1 name:dog useless:null 地址:com.xue.qin.demo.myserialization.MyObject@b4abe69 ) 01-04 18:21:58.311 18984-18984/? I/ObjectNet: obj5 = ( n:1 name:dog useless:null 地址:com.xue.qin.demo.myserialization.MyObject@b4abe69 ) 01-04 18:21:58.311 18984-18984/? I/ObjectNet: obj6 = ( n:2 name:cat useless:null 地址:com.xue.qin.demo.myserialization.MyObject@30d40ee )
可以看到,写入时候地址完全一致,符合我们一贯的想法,没啥说的。读取回来的obj4和obj5地址也是一致的,也就是说obj4和obj5是指向同一个引用的。
可见序列化的时候是将引用的关系也写入了,并不是简单的根据引用复制一个对象,而是还复制了对象的指向关系。
另外作为transient 标记的变量useless没有被序列化。
(二)Parcelable
android为了进程间的通信能够高效率的传送信息,使用parcel,必须要接入这个接口parcelable。代码例子如下,使用中可以接入此接口。
package com.xue.qin.demo.myparcelableclass;import android.os.Parcel;import android.os.Parcelable;/** * Created by xue.qin on 2017/6/5. */public class MyObject implements Parcelable { private int n; private String name; private String useless; public MyObject(){ n=0; name="default"; useless="default"; } public MyObject(int n, String name, String useless) { this.n = n; this.name = name; this.useless = useless; } public MyObject(Parcel source) { readFromParcel(source); } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(n); dest.writeString(name); dest.writeString(useless); } public void readFromParcel(Parcel source) { this.n = source.readInt(); this.name = source.readString(); this.useless = source.readString(); } public static final Parcelable.Creator<MyObject> CREATOR = new Creator<MyObject>() { @Override public MyObject createFromParcel(Parcel source) { MyObject myObject2 = new MyObject(source); return myObject2; } @Override public MyObject[] newArray(int size) { return new MyObject[size]; } }; @Override public String toString() { return "( n:" + n + " name:" + name + " useless:" + useless + " 地址:" + super.toString() + " )"; }}
关键点1、必须有无参数构造函数。(参数定向tag为 out , inout ,会调用)
关键点2、必须按照规范写 writeToParcel和readFromParcel(为什么Parcelable接口中没有这个方法??),(参数定向tag为 out , inout ,会调用))
关键点3、必须按照规范写 public static final Parcelable.Creator<MyObject> CREATOR = new Creator<MyObject>()
接口提供了可供外部调用的静态对象,提供从parcel读取初始化类实例的渠道。,
问题:为什么非得声明为CREATE这个变量名?
是因为例如在AIDL自动生成的代码中就会使用者个变量来创建parcelable的类实例。(相信系统中还要有类似的调用与写法,例如系统中的MotionEvent类就是这样写的)
com.xue.qin.demo.myparcelableclass.MyObject.CREATOR.createFromParcel(data);
既然安卓提供了这样简洁的写法与规定,最好写成CREATOR。
- Android中序列化
- Android中序列化
- android 中序列化对象
- Android中xml解析和序列化
- Android中Parcelable序列化总结
- android中对象序列化存储
- Android中Parcelable序列化总结
- Android中使用Parcelable序列化对象
- Android中序列化的实现
- Android中Parcelable序列化小结
- Android中XML文件的序列化
- Android 对象序列化 Java中实现Serializable序列化与Android特有的实现Parceable接口序列化操作
- Android中SharedPreferences和序列化结合保存对象数据
- Android绘图中Path无法序列化的问题解决思路
- Android 中对象实现序列化之Parcelable接口
- Android中SharedPreferences使用和xml解析和序列化
- Android中SharedPreferences和序列化结合保存对象数据
- Android中传送序列化对象出现的ClassNotFoundException解决办法
- Kotlin入门系列教程—String
- nginx-视频直播和点播服务的干货分享
- c++的代码重用
- win7下80端口被(Pid=4)占用的解决方法
- Python+Selenium学习遇到的问题总结(一)
- Android中序列化
- Android
- 单链表逆序 多种方法总结
- inline-block的默认间距
- 使用Android常用控件与布局实现美观的登录页面
- C++基于TCP/IP简单的客户端、服务器通信程序实例
- (笔记)色彩原理
- 332. Reconstruct Itinerary
- java多线程管理 concurrent包用法详解