几种Android数据序列化方案
一、引言
数据的序列化在Android开发中占据着重要的地位,无论是在进程间通信、本地数据存储又或者是网络数据传输都离不开序列化的支持。而针对不同场景选择合适的序列化方案对于应用的性能有着极大的影响。
从广义上讲,数据序列化就是将数据结构或者是对象转换成我们可以存储或者传输的数据格式的一个过程,在序列化的过程中,数据结构或者对象将其状态信息写入到临时或者持久性的存储区中,而在对应的反序列化过程中,则可以说是生成的数据被还原成数据结构或对象的过程。
这样来说,数据序列化相当于是将我们原先的对象序列化概念做出了扩展,在对象序列化和反序列化中,我们熟知的有两种方法,其一是Java语言中提供的Serializable接口,其二是Android提供的Parcelable接口。而在这里,因为我们对这个概念做出了扩展,因此也需要考虑几种专门针对数据结构进行序列化的方法,如现在那些个开放API一般返回的数据都是JSON格式的,又或者是我们Android原生的SQLite数据库来实现数据的本地存储,从广义上来说,这些都可以算做是数据的序列化。
二、Serializable接口
正如前面提到的,Serializable接口是Java语言的特性,是最简单也是使用最广泛的序列化方案之一,这边需要注意的一点是Serializable接口是一个标识接口,无需实现方法,Java便会对这个对象进行序列化操作。
在这里实现了Serializable接口的对象才可以序列化,将Java对象转换成字节序列,而对应的反序列化则是将字节序列恢复成Java对象的过程。
在需要序列化的类中会用到serialVersionUID去标识这个序列化对象,即仅当序列化后的数据中的SerialVersionUID与当前类的serialVersionUID相同时才能被正常的反序列化。
import java.io.*;
public class User implements Serializable{
private static final long serialVersionUID= 123456;
public int userId;
public String userName;
public boolean isMale;
public User(int userId,String userName,boolean isMale){
this.userId=userId;
this.userName=userName;
this.isMale = isMale;
}
public boolean toSerial(User user) throws IOException{
ObjectOutputStream out=null;
boolean status=false;
try{
out = new ObjectOutputStream(new FileOutputStream("cache.txt"));
out.writeObject(user);
status=true;
}catch(FileNotFoundException e){
System.out.println("NO FILE");
}finally{
if(out!=null)
out.close();
}
return status;
}
public User toObject(String filename) throws IOException{
ObjectInputStream in=null;
boolean status=false;
User user=null;
try{
in = new ObjectInputStream(new FileInputStream(filename));
user=(User) in.readObject();
}catch(ClassNotFoundException e){
System.out.println("No file");
}finally{
if(in!=null)
in.close();
}
return user;
}
public static void main(String[] args) throws IOException{
User user = new User(0,"jake",true);
System.out.println(user.toSerial(user));
System.out.println(user.toObject("cache.txt").getClass());
}
}
此外,需要注意的:静态成员变量是属于类而不属于对象的,所以显然它不会参与到对象的序列化过程中。其次用transient关键字标记的成员变量不参与到序列化过程中。最后,这种序列化方式是基于磁盘或者网络的。
三、Parcelable接口
Parcelable接口是Android API提供的接口,从某种程度上来说,它更适用于Android平台上。不同于Serializable,它是基于内存的,由于内存中读写速度高于磁盘,所以Parcelable接口被广泛用于跨进程对象的传递。
下面贴上一个简单的Parcelable接口的序列化过程:
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable {
public int userId;
public String userName;
public boolean isMale;
public User(int userId,String userName,boolean isMale) {
this.userId=userId;
this.userName=userName;
this.isMale=isMale;
} public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
} @Override
public User[] newArray(int size) {
return new User[size];
}
}; public User(Parcel in) {
userId=in.readInt();
userName = in.readString();
isMale=in.readInt()==1;
} @Override
public int describeContents() {
return 0;
} @Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(userId);
out.writeString(userName);
out.writeInt(isMale?1:0);
}
}
从上面可以看出,实现一个Parcelable接口,需要实现以下几个方法:
1.构造函数:从序列化后的对象中创建原始对象
2.describeContents :接口内容的描述,一般默认返回0即可
3.writeToParcel:序列化的方法,将类的数据写到parcel容器中
4.静态的parcelable.Creator接口,这个接口包含两个方法
1)createFormParcel:反序列化的方法,将Parcel还原成Java对象
2)newArray:提供给外部类反序列化这个数组使用。
四、两种对象序列化方法的对比
Serializable是Java中的序列化接口,其使用起来简单但开销较大(因为Serializable在序列化过程中使用了反射机制,故而会产生大量的临时变量,从而导致频繁的GC),并且在读写数据过程中,它是通过IO流的形式将数据写入到硬盘或者传输到网络上。
而Parcelable则是以IBinder作为信息载体,在内存上开销比较小,因此在内存之间进行数据传递时,推荐使用Parcelable,而Parcelable对数据进行持久化或者网络传输时操作复杂,一般这个时候推荐使用Serializable。
另外Serializable在使用时比较简单,而Parcelable在使用时需要手动去实现接口中的方法,为了规避使用Parcelable接口时的麻烦,我们下面介绍一个插件,从而自动生成对应的代码。
五、Parcelable插件
为了避免写大量的模板代码,这边介绍一个在Android Strudio中的插件,Android Parcelable code generator。在Pulgins中下载并按照该插件,接下来当我们需要用到Parcelable接口时,该插件就能自动帮我们将类对象转换成实现Parcelable接口的形式。
具体示例如下,
/**
* Created by DB on 2017/6/24.
*/ public class BookItem {
public String mName;
public long mLastTime;
public String mTitle;
public String mPath;
}
然后类似与生成getter和setter代码那样,我们就可以直接自动生成Parcelable形式的代码,结果如下所示:
import android.os.Parcel;
import android.os.Parcelable; /**
* Created by DB on 2017/6/24.
*/ public class BookItem implements Parcelable {
public String mName;
public long mLastTime;
public String mTitle;
public String mPath; @Override
public int describeContents() {
return 0;
} @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.mName);
dest.writeLong(this.mLastTime);
dest.writeString(this.mTitle);
dest.writeString(this.mPath);
} public BookItem() {
} protected BookItem(Parcel in) {
this.mName = in.readString();
this.mLastTime = in.readLong();
this.mTitle = in.readString();
this.mPath = in.readString();
} public static final Parcelable.Creator<BookItem> CREATOR = new Parcelable.Creator<BookItem>() {
@Override
public BookItem createFromParcel(Parcel source) {
return new BookItem(source);
} @Override
public BookItem[] newArray(int size) {
return new BookItem[size];
}
};
}
有了这个插件,使用Parcelable接口显然方便了许多(可以偷好多懒)
六、数据的序列化方案
下面讲到的是广义上的序列化方案,不同于前面两种狭义或者说是对象序列化方案,接下来的几种方案针对于数据的传输和存储过程中的序列化方案
1.SQLite
SQLite主要用于存储复杂的关系型数据,Android支持原生支持SQLite数据库相关操作(SQLiteOpenHelper),不过由于原生API接口并不友好,所以产生了不少封装了SQLite的ORM框架。
2.SharedPreferences
SharedPreferences是Android平台上提供的一个轻量级存储API,一般用于存储常用的配置信息,其本质是一个键值对存储,支持常用的数据类型如boolean、float、int、long以及String的存储和读取。
使用SharedPreferences读取和存储操作如下:
读取:
1) 获取Sharedpreferences对象
SharedPreferences mPreferences = context.getCSharedPreferences(PREFERENCES_NAME,Context.MODE_PRIVATE);
2.通过SharedPReferences对象读取存储在SharedPreferences中的数据
mPreferences.getBoolean(key,defValue);
存储:
1)获取SharedPreferences.Editor对象
SharedPreferences.Editor editor = mPreferences.edit();
2)通过SharedPreferences.Editor对象写入数据到SharedPreferences中。
mEditor.putBoolean(key,b);
3)调用commit函数将写入的数据提交,从而完成数据存储操作。
mEditor.commit();
3.JSON
JSON是一种轻量级的数据交互格式,由于其相对于XML,体积更小,在网络上传输时更加介绍浏览,被广泛用于移动端。大部分APP与服务端的通信都是使用JSON格式进行交互。
几种Android数据序列化方案的更多相关文章
- 一种Android数据请求框架
大部分Android应用一般都涉及到跟server的交互,除非是某些单机应用.既然要跟server打交道,向server请求数据差点儿是必做的事情,或许每家的APP都有一套自己的详细实现逻辑.但我们还 ...
- C基础 数据序列化简单使用和讨论
前言 C中对序列化讨论少, 因为很多传输的内容都有自己解析的轮子. 对于序列化本质是统一编码, 统一解码的方式. 本文探讨是一种简单的序列化方案. 保证不同使用端都能解析出正确结果. 在文章一开始, ...
- 数据序列化导读(1)[JSON]
所谓数据序列化(Data Serialization), 就是将某个对象的状态信息转换为可以存储或传输的形式的过程. 那么,为什么要进行序列化? 首先,为了方便数据存储: 其次,为了方便数据传递. 在 ...
- Android Learning:数据存储方案归纳与总结
前言 最近在学习<第一行android代码>和<疯狂android讲义>,我的感触是Android应用的本质其实就是数据的处理,包括数据的接收,存储,处理以及显示,我想针对这几 ...
- 最经常使用的两种C++序列化方案的使用心得(protobuf和boost serialization)
导读 1. 什么是序列化? 2. 为什么要序列化?优点在哪里? 3. C++对象序列化的四种方法 4. 最经常使用的两种序列化方案使用心得 正文 1. 什么是序列化? 程序猿在编写应用程序的时候往往须 ...
- 最常用的两种C++序列化方案的使用心得(protobuf和boost serialization)
导读 1. 什么是序列化? 2. 为什么要序列化?好处在哪里? 3. C++对象序列化的四种方法 4. 最常用的两种序列化方案使用心得 正文 1. 什么是序列化? 程序员在编写应用程序的时候往往需要将 ...
- iOS中几种数据持久化方案
概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) ...
- Android数据传递的五种方法汇总
Android开发中,在不同模块(如Activity)间经常会有各种各样的数据需要相互传递,我把常用的几种 方法都收集到了一起.它们各有利弊,有各自的应用场景. 我现在把它们集中到一个例子中展示,在例 ...
- PHP四种序列化方案
原文地址:https://t.ti-node.com/thread/... 数据的序列化是一个非常有用的功能,然而目测很多人跟我一样,在刚接触这玩意的时候压根就不理解这货色到底是干啥用的,反正老师说了 ...
随机推荐
- 【NLP】3000篇搜狐新闻语料数据预处理器的python实现
3000篇搜狐新闻语料数据预处理器的python实现 白宁超 2017年5月5日17:20:04 摘要: 关于自然语言处理模型训练亦或是数据挖掘.文本处理等等,均离不开数据清洗,数据预处理的工作.这里 ...
- vue.js2.0 自定义组件初体验
理解 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能.在有些情况 ...
- <javaScript> 数组去重的方法总结(2017年)
现在要求去重下面这个数组: const arr = [1, 2, 3, 3, 3, '0', '1', '2', '测试', '重复', '重复', NaN, NaN, false, false]; ...
- 关于Dubbo一个接口多个实现的解决方案
如题,其实这个问题在官方文档中已经说明了.我直接贴图就好了 更多学习请参考:minglisoft.cn/technology
- trap-接收信号_采取行动
trap命令用于指定在接收到信号后将要采取的动作,常见的用途是在脚本程序被中断时完成清理工作. kill和trap等都可以看到信号编号及其关联的名称. "信号"是指那些被异步发送到 ...
- 加盟全景-加盟VR虚拟现实-全景智慧城市
作为一个技术整合型产业,VR行业的硬件厂商几乎没有任何技术基础,很多国产虚拟现实VR创业公司基本都是和几家固定的上游零部件提供商合作,全行业都在等待高通骁龙芯片的升级,这和手机行业有几分相似.去年3月 ...
- 【踩坑】360安全浏览器“极速模式”和“兼容模式”,套路还是bug?
分享踩坑点: 项目中需要兼容360安全浏览器,大家当然都希望用极速模式打开网站,但是发现总是被兼容模式打开 网址类似 aa.xx.dd.com 网上找了很多地方,有以下两种方法 1.<meta ...
- Java Synchronization
Volatile Since Java 5 the volatile keyword guarantees more than just the reading from and writing to ...
- Linux parent process and child process when 'sudo'
如果在一般用户下如user,执行sudo命令,会产生两个进程. ps -ef | grep Container root 4305 643 0 16:37 pts/39 00:00:00 sudo . ...
- 《算法4》1.5 - Union-Find 算法解决动态连通性问题,Python实现
Union-Find 算法(中文称并查集算法)是解决动态连通性(Dynamic Conectivity)问题的一种算法,作者以此为实例,讲述了如何分析和改进算法,本节涉及三个算法实现,分别是Quick ...