Android Parcelable對象序列化到磁盤以及反序列化

前言:抱着最起碼的要求盡力去做好每一件事 ! ——秋不白

內容如題,僅個人探討,以下代碼都測試通過。

        記錄一次面試經歷:面試官問到Serializable和Parcelable 的主要區別是什麼,我說把知道的說了一遍,效率,S屬於java api,P屬於Android ,以及序列化的使用場景。他說不對,然後說S是系列化到磁盤,P是序列化到內存。我就百思不得其姐,決定好好研究一下。

     查找資料 以及根據AS自動生成的代碼,可以理解,Parcelable的序列化和反序列化操作實際是,Parcel內部包裝了可序列化的數據,也就是說序列化的時候,將數據放入,parcel的write方法,反序列化是通過CREATOR來完成的,通過獲取當前線程的上下文加載器,並通過parcel的read方法,來完成反序列化操作。代碼如下

Person 實體類

/**
 * Desc:
 *
 * @author: RedRose
 * Date: 2019/5/3
 * Email: [email protected]
 */

public class Person implements Parcelable {
    private int age;
    private String name;

    public Person(int age, String name) {
        this.age = age;
        this.name = name;
    }

    private Person(Parcel in) {
        age = in.readInt();
        name = in.readString();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(age);
        dest.writeString(name);
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

具體的序列化和反序列化

              //將parcelable 對象序列化到磁盤
            case R.id.testParcelable:
                File file = new File(PathUtil.getAppDocPath() + "testParcelable.txt");
                try {
                    if (!file.exists()) {
                        file.createNewFile();
                    }
                    Person p = new Person(1, "XueQin");
                    FileOutputStream out = (new FileOutputStream(file));
                    BufferedOutputStream bos = new BufferedOutputStream(out);
                    Parcel parcel = Parcel.obtain();
                    parcel.writeParcelable(p,0);
                    bos.write(parcel.marshall());
                    bos.flush();
                    bos.close();
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
                //反序列化parcelable對象
            case R.id.readParcelable:
                try {
                    File file2 = new File(PathUtil.getAppDocPath() + "testParcelable.txt");
                    FileInputStream in = new FileInputStream(file2);
                    byte[] bytes = new byte[in.available()];
                    in.read(bytes);
                    Parcel parcel = Parcel.obtain();
                    parcel.unmarshall(bytes, 0, bytes.length);
                    parcel.setDataPosition(0);
                    Person person = parcel.readParcelable(Thread.currentThread().getContextClassLoader());
                    in.close();
                    LogUtils.e(TAG, person.toString());
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;

以及parcel的readParcelable的源碼,可以參考下,通過當前線程的上下文類加載器獲取到CREAOR對象。

  @SuppressWarnings("unchecked")
    public final <T extends Parcelable> T readParcelable(ClassLoader loader) {
        Parcelable.Creator<?> creator = readParcelableCreator(loader);
        if (creator == null) {
            return null;
        }
        if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
          Parcelable.ClassLoaderCreator<?> classLoaderCreator =
              (Parcelable.ClassLoaderCreator<?>) creator;
          return (T) classLoaderCreator.createFromParcel(this, loader);
        }
        return (T) creator.createFromParcel(this);
    }

總結:知識如浩瀚的海洋,加油吧,我們一起。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章