知人者智,自知者明。胜人者有力,自胜者强。——老子

最近在总结Activity之间数据传递的类型,我们都知道当Android中需要传递对象时一般要实现Serializable或Parcelable接口,但是只会写,对其一些内在的原理一点也不了解,阅读了多篇博客并亲自验证后,决定对Serializable和Parcelable的原理和使用做一个总结,如有谬误欢迎指正,如有疑问欢迎留言。我将在第一时间回答或改正。

一、Serializable意思是序列化,什么是序列化与反序列化? 对象的序列化:把对象转换为字节序列的过程称为对象的序列化 反序列化:把字节序列恢复为Java对象的过程。 要想搞清楚序列化我们必须要清楚三点:Java对象、字节序列、存储。 ①Java对象 Java对象包含变量与方法。但是序列与反序列化仅处理Java变量而不处理方法,序列与反序列化仅对数据进行处理。 ②字节序列
其实就是连续排列的多个字符的序列,例如:“asdsdsfsdfsdff”
③存储 字符序列需要保存到一个地方,可以是硬盘也可以是内存。
简单说法是:序列化把当前对象信息保存下来。反序列化刚好相反的操作。 二、为什么要使用序列化? 在了解什么是序列化后可能会有人问为什么要使用序列化?它有什么用处? 从序列化的定义中我们可以看到它把一个对象转换成了流,并且将其保存到本地,那么我们就可以知道序列化主要有以下用途 (1)永久性保存对象,保存对象的字节序列到本地文件中; (2)通过序列化对象在网络中传递对象; (3)通过序列化在进程间传递对象(如:android通过序列化传递对象)。 、Java对象与Java对象序列化的区别? Java对象存在的前提必须在JVM运行期间存在,如果想在JVM非运行的情况下或者在其他机器JVM上获取指定Java对象,在现有Java对象的机制下都不可能完成。
与Java对象不同的是,如果对Java对象执行序列化操作,因为原理是把Java对象信息保存到存储媒介,所以可以在以上Java对象不可能存在的两种情况下依然可以使用Java对象。
四、如何实现序列化 Android中实现序列化有两个选择:一是实现Serializable接口(是JavaSE本身就支持的),一是实现Parcelable接口(是Android特有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC))。实现Serializable接口非常简单,声明一下就可以了,而实现Parcelable接口稍微复杂一些,但效率更高,推荐用这种方法提高性能。

注:Android中Intent传递对象有两种方法:一是Bundle.putSerializable(Key,Object),另一种是Bundle.putParcelable(Key,Object)。当然这些Object是有一定的条件的,前者是实现了Serializable接口,而后者是实现了Parcelable接口。 两种序列化方法的比较: Serializable, 简单易用,效率低 serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可。Serializable 接口是一种标识接口(marker interface),这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。 这种方法的缺点是使用了反射,序列化的过程较慢。这种机制会在序列化的时候创建许多的临时对象,容易触发垃圾回收。 Parcelable, 速度至上,代码量阅读和维护不易 根据Google工程师的说法,这些代码将会运行地特别快。原因之一就是我们已经清楚地知道了序列化的过程,而不需要使用反射来推断。同时为了更快地进行序列化,对象的代码也需要高度优化。因此,很明显实现Parcelable并不容易。实现Parcelable接口需要写大量的模板代码,这使得对象代码变得难以阅读和维护。 关于 Parcelable比 Serializable运行快慢的比较详见此博客 http://greenrobot.me/devpost/android-parcelable-serializable/ Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。而Android的Parcelable的设计初衷是因为Serializable效率过慢为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。从Parcelable设计的初衷中我们也能够看到Parcelable的速度是比较快的那么我们如何选择使用哪种序列化方式呢?
如果你想成为一个优秀的软件工程师,你需要多花点时间来实现Parcelable因为这将会为你对象的序列化过程快10多倍,而且占用较少的资源。 五、Parcelable接口定义
public interface Parcelable    {        //内容描述接口,基本不用管        public int describeContents();        //写入接口函数,打包        public void writeToParcel(Parcel dest, int flags);        //读取接口,目的是要从Parcel中构造一个实现了 Parcelable的类的实例处理。因为实现类在这里还是不可知的,所以需要用到模板的方式,继承类名通过模板参数<span style="white-space:pre"></span>  传入<span style="white-space:pre"></span>        //为了能够实现模板参数的传入,这里定义Creator嵌入接口,内含两个接口函数分别返回单个和多个继承类实例        public interface Creator<T>        {               public T createFromParcel(Parcel source);               public T[] newArray( int size);        }     }
六、应用举例
①实现Parcelable
实现Parcelable大致可以分为四个步骤:
1)implements Parcelable
2)重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数 据到Parcel容器保存,以便从 Parcel容器获取数据
3)重写describeContents方法,内容接口描述,默认返回0就可以
4)实例化静态内部对象CREATOR实现接口Parcelable.Creator
public static final Parcelable.Creator<T> CREATOR
注: 其中public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写 。需重写本接口中的两个方法:createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。
从Parcelable的实现步骤我们可以看到在此过程中: 通过writeToParcel将对象映射到Parceld对象,然后再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,在通过createFromParcel从流里读取对象,只不过这个过程需要我们来实现, 因此写的顺序和读的顺序必须一
创建一个实现了Parcelable接口的类 Book类
package com.example.progressbar;import android.os.Parcel;import android.os.Parcelable;public class Book implements Parcelable {     private String name;     private int price;private String author;     public Book() {}     public Book(String name, int price, String author) {     this.name = name;     this.price = price;     this.author = author;}     public String getName() {      return name; }     public void setName(String name) {     this.name = name;}     public int getPrice() {     return price;}public void setPrice(int price) {     this.price = price;}public String getAuthor() {     return author;}    public void setAuthor(String author) {      this.author = author;}  @Overridepublic int describeContents() {      return 0;}// 该方法将类的数据写入外部提供的Parcel中。@Overridepublic void writeToParcel(Parcel parcel, int i) {     parcel.writeString(this.name);     parcel.writeInt(this.price);     parcel.writeString(this.author);}  public static final Parcelable.Creator<Book> CREATOR = new Creator<Book>() {// 返回一个Book[i]供外部类反序列化本类数组使用 @Overridepublic Book[] newArray(int i) {             return new Book[i];}         @Override       public Book createFromParcel(Parcel parcel) {// 将Parcel对象反序列化为Book对象return new Book(parcel.readString(),parcel.readInt(),parcel.readString());           }     };}
创建Student类实现Serializable,实现Serializable比较简单只需要implements Serializable 即可。这只是给对象打了一个标记,系统会自动将其序列化。 Student类
packagecom.example.progressbar;import java.io.Serializable;publicclassStudent implements Serializable { private static final long serialVersionUID = 1L;private String name;  private int age;private String sex;         public Student(){}   public Student(String name,int age,String sex){                 this.name=name;                  this.age=age;                 this.sex=sex;}  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;} public String getSex() {                return sex;}  public void setSex(String sex) {      this.sex = sex;   }}
好了,这一篇博客就到这里了,看完了就留个言顶一个呗,您的支持是我前进的动力。






更多相关文章

  1. android添加wifi热点管理黑白名单
  2. Android(安卓)Training - 代码性能优化小技巧
  3. java/android 设计模式学习笔记(12)---组合模式
  4. AndroidCameraHAL3-MultiCamera-CameraX
  5. Service与Android系统设计(2)-- Parcel
  6. Activity任务栈和启动模式
  7. Android可绘制对象资源之shape和layer-list使用
  8. Android(安卓)SAX方式解析XML文件
  9. android直播中的一些流媒体技术浅析

随机推荐

  1. Android 性能优化系列总篇 (五)
  2. 系出名门Android(9) - 数据库支持(SQLite
  3. Android中backgroundDimEnabled的作用
  4. android:属性 layout_alignParentRight an
  5. android 组件属性描述
  6. android 导入项目报错
  7. LinearLayout布局实现垂直水平居中
  8. Android安卓布局简介
  9. Android图表控件MPAndroidChart——曲线
  10. android与j2me移植之clipRect