Android序列化简析

作者: RaphetS | 来源:发表于2016-11-04 09:51 被阅读1483次

    目录
    1、序列化与反序列化概念
    2、序列化用途
    3、Serializable实现序列化
    4、 Parcelable实现序列化
    5、Serializable与Parcelable区别

    参考资料:Android开发艺术探索

    一、概念

    Java序列化是指把Java对象转换为字节序列的过程;

    而Java反序列化是指把字节序列恢复为Java对象的过程。

    二、用途

    1、实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里)

    2、通过序列化对象在网络中传递对象。

    3、通过序列化对象在进程间传递对象。

    三、Serializable实现序列化

    Serializable的作用是为了保存对象的属性到本地文件、数据库、网络流、rmi以方便数据传输,当然这种传输可以是程序内的也可以是两个程序间的

    对于Serializable,类只需要实现Serializable接口,并提供一个序列化版本id(serialVersionUID)即可

    Android Studio自动生成SerizlVersionUID:

    1、File -> Settings... -> Editor -> Inspections -> Serialization issues -> Serializable class without ‘serialVersionUID‘(选中)

    2、进入实现了Serializable中的类,选中类名,Alt+Enter弹出提示,然后直接导入完成.

    package org.raphets.democollection;
    
    
    import java.io.Serializable;
    
    public class Dog implements Serializable{
    
        private static final long serialVersionUID = -2457171891775313955L;
        
        private String name;
        private int age;
    
        public Dog(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        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;
        }
    
    
    }
    
    
    利用Serializable保存对象到本地
    package org.raphets.democollection;
    
    import android.os.Environment;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.LinkedList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            storageSerializableData();
            getSerializableData();
        }
    
    
        /**
         * 存储Serializable数据到本地
         */
        private void storageSerializableData() {
            List<Dog> mDogs = new ArrayList<>();
            Dog dog1 = new Dog("a", 3);
            Dog dog2 = new Dog("b", 4);
            Dog dog3 = new Dog("c", 2);
    
            mDogs.add(dog1);
            mDogs.add(dog2);
            mDogs.add(dog3);
    
            FileOutputStream fos = null;
            ObjectOutputStream oos = null;
    
            try {
    
                File file = new File(Environment.getExternalStorageDirectory().toString()
                        + "/" + "dogs.dat");
                if (!file.exists()) {
                    file.createNewFile();
                }
                fos = new FileOutputStream(file.toString());
                oos = new ObjectOutputStream(fos);
                oos.writeObject(mDogs);
            } catch (Exception e) {
                Log.i("TAG",e.toString());
            } finally {
    
                try {
                    if (oos != null)
                        oos.close();
                    if (fos != null)
                        fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
    
            }
    
        }
    
        /**
         * 读取本地的Seriablizable数据
         */
        private void getSerializableData() {
            FileInputStream fis=null;
            ObjectInputStream ois=null;
            File file = new File(Environment.getExternalStorageDirectory().toString()
                    + "/" + "dogs.dat");
            if (file.exists()){
                try {
                    fis=new FileInputStream(file.toString());
                    ois=new ObjectInputStream(fis);
                   List<Dog> mDogs= (List<Dog>) ois.readObject();
                    for (Dog dog:mDogs){
                        Log.i("Dog",dog.getName());
                    }
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
    
    }
    
    

    四、 Parcelable实现序列化

    Android的Parcelable的设计初衷是因为Serializable效率过慢,为了在程序内不同组件间以及不同Android程序间(AIDL)高效的传输数据而设计,这些数据仅在内存中存在,Parcelable是通过IBinder通信的消息的载体。

    实现Parcelable接口主要可以分为一下几步:

    1)implements Parcelable。

    2)重写writeToParcel方法,将你的对象序列化为一个Parcel对象,即:将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从Parcel容器获取数据。

    3)重写describeContents方法,内容接口描述,默认返回0即可。

    4)实例化静态内部对象CREATOR实现接口Parcelable.Creator 。
    注意:若将Parcel看成是一个流,则先通过writeToParcel把对象写到流里面,再通过createFromParcel从流里读取对象,因此类实现的写入顺序和读出顺序必须一致。

    package org.raphets.democollection;
    
    
    import android.os.Parcel;
    import android.os.Parcelable;
    
    public class Dog implements Parcelable{
    
        private String name;
        private int age;
    
        protected Dog(Parcel in) {
            name = in.readString();
            age = in.readInt();
        }
    
        public Dog(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        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 static final Creator<Dog> CREATOR = new Creator<Dog>() {
            @Override
            public Dog createFromParcel(Parcel in) {
                return new Dog(in);
            }
    
            @Override
            public Dog[] newArray(int size) {
                return new Dog[size];
            }
        };
    
        @Override
        public int describeContents() {
            return 0;
        }
    
        @Override
        public void writeToParcel(Parcel parcel, int i) {
            parcel.writeString(name);
            parcel.writeInt(age);
        }
    }
    
    

    五、Parcelable和Serializable的区别:

    1、在使用内存的时候Parcelable比Serializable的性能高。

    2、Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC(内存回收)。

    3、Parcelable不能使用在将对象存储在磁盘上这种情况,因为在外界的变化下Parcelable不能很好的保证数据的持续性。

    4、在读写数据的时候,Parcelable是在内存中直接进行读写,而Serializable是通过使用IO流的形式将数据读写入在硬盘上

    5、Parcelable是以Ibinder作为信息载体的.在内存上的开销比较小,因此在内存之间进行数据传递的时候,Android推荐使用Parcelable

    如何选择

    Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化

    相关文章

      网友评论

        本文标题:Android序列化简析

        本文链接:https://www.haomeiwen.com/subject/pswiuttx.html