• Android 序列化比对


    本文转自:https://www.zybuluo.com/linux1s1s/note/91046

    注:部分内容有更改

    在Android中使用序列化,无非两种途经: Parcelable 和 Serializable

    两者区别

    • Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。
    • Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。如果想进一步了解进程间通信AIDL方式可以看博文:Android 进程间通信IPC_AIDL
    • Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据
    • Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化

    Serializable

    public class SerializableDeveloper implements Serializable
        String name;
        int yearsOfExperience;
        List<Skill> skillSet;
        float favoriteFloat;
        static class Skill implements Serializable {
            String name;
            boolean programmingRelated;
        }
    }

    serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可。Serializable 接口是一种标识接口(marker interface),这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。 
    这种方法的缺点是使用了反射,序列化的过程较慢。这种机制会在序列化的时候创建许多的临时对象,容易触发垃圾回收。

    Parcelable

    public class Video implements Parcelable {
        private long id;
        private String picture;
        private String title;
        private String author;
        private String duration;
        private String uploadTime;
    
        public Video() {
        }
    
        public Video(Parcel input) {
            id = input.readLong();
            picture = input.readString();
            title = input.readString();
            author = input.readString();
            duration = input.readString();
            uploadTime = input.readString();
        }
    
        public Video(long id, String picture, String title, String author, String duration, String uploadTime) {
            this.author = author;
            this.duration = duration;
            this.id = id;
            this.picture = picture;
            this.title = title;
            this.uploadTime = uploadTime;
        }
    
        public String getAuthor() {
            return author;
        }
    
        public void setAuthor(String author) {
            this.author = author;
        }
    
        public String getDuration() {
            return duration;
        }
    
        public void setDuration(String duration) {
            this.duration = duration;
        }
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        public String getPicture() {
            return picture;
        }
    
        public void setPicture(String picture) {
            this.picture = picture;
        }
    
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String getUploadTime() {
            return uploadTime;
        }
    
        public void setUploadTime(String uploadTime) {
            this.uploadTime = uploadTime;
        }
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeLong(id);
            dest.writeString(picture);
            dest.writeString(title);
            dest.writeString(author);
            dest.writeString(duration);
            dest.writeString(uploadTime);
        }
    
        public static final Parcelable.Creator<Video> CREATOR = new Parcelable.Creator<Video>() {
    
            @Override
            public Video createFromParcel(Parcel source) {
                return new Video(source);
            }
    
            @Override
            public Video[] newArray(int size) {
                return new Video[size];
            }
        };
    }

    根据 google 工程师的说法,这些代码将会运行地特别快。原因之一就是我们已经清楚地知道了序列化的过程,而不需要使用反射来推断。同时为了更快地进行序列化,对象的代码也需要高度优化。 
    因此,很明显实现Parcelable并不容易。实现Parcelable接口需要写大量的模板代码,这使得对象代码变得难以阅读和维护。

    性能测试

    通过将一个对象放到一个bundle里面然后调用Bundle#writeToParcel(Parcel, int)方法来模拟传递对象给一个activity的过程,然后再把这个对象取出来,在一个循环里面运行1000 次。

    小结

    如果你想成为一个优秀的软件工程师,你需要多花点时间来实现 Parcelable ,因为这将会为你对象的序列化过程快10多倍,而且占用较少的资源。

    但是大多数情况下, Serializable 的龟速不会太引人注目。你想偷点懒就用它吧,不过要记得serialization是一个比较耗资源的操作,尽量少使用。

    如果你想要传递一个包含许多对象的列表,那么整个序列化的过程的时间开销可能会超过一秒,这会让屏幕转向的时候变得很卡顿

    另外有一种说法是:在Activity之间传递数据使用Serializable在某种情况下会失败,这样的案例尚未遇到过。(个人猜测:难道是持久化数据需要写入扩展SD卡,如果一旦出现写入或者读取失败,那么传输就会失败)

    本文翻译和整理自:http://www.developerphil.com/parcelable-vs-serializable/

  • 相关阅读:
    c++ const的使用
    C++面向对象程序设计举例
    C++构造函数与析构函数的解析
    inline函数和一般的函数有什么不同
    Linux 脚本为什么会有#!
    Linux 基本概念和操作2
    Linux 基本概念和操作
    ubuntu14.0464位 Ros环境 安装halcon13.01
    数据类型之间的连接和运算
    cmd命令 从C盘转到D盘
  • 原文地址:https://www.cnblogs.com/lurenjiashuo/p/android-parcelable-vs-serializable.html
Copyright © 2020-2023  润新知