Parcelable 和 Serializable 区别
-
Serializable IO完成(通过磁盘文件读写)
-
Parcelable C++ 对象指针 来实现共享内存
import android.os.Parcel;
import androidx.annotation.NonNull;public class ApiResponseBean extends Throwable implements Parcelable {private boolean success;private String msg;protected ApiResponseBean(Parcel in) {success = in.readByte() != 0;msg = in.readString();}public static final Creator<ApiResponseBean> CREATOR = new Creator<ApiResponseBean>() {@Overridepublic ApiResponseBean createFromParcel(Parcel in) {return new ApiResponseBean(in);}@Overridepublic ApiResponseBean[] newArray(int size) {return new ApiResponseBean[size];}};@Overridepublic int describeContents() {return 0;}@Overridepublic void writeToParcel(@NonNull Parcel dest, int flags) {dest.writeInt(success?1:0);dest.writeString(msg);}
}
数据序列化的部分写入和读取的顺序不能乱,C++根据指针下标来读取数据;
Parcel.obtain 对象池 Handler message.obtain
- 私有 Parcel 防止直接 new 通过 obtain 获取;
- 单例 同步锁 对象池
静态链表的结构 形成一个对象池;
/*** Retrieve a new Parcel object from the pool.*/@NonNullpublic static Parcel obtain() {Parcel res = null;synchronized (sPoolSync) {if (sOwnedPool != null) {res = sOwnedPool;sOwnedPool = res.mPoolNext;res.mPoolNext = null;sOwnedPoolSize--;}}// When no cache found above, create from scratch; otherwise prepare the// cached object to be usedif (res == null) {res = new Parcel(0);} else {if (DEBUG_RECYCLE) {res.mStack = new RuntimeException();}res.mReadWriteHelper = ReadWriteHelper.DEFAULT;}return res;}
Parcel 设计思路
- nativeptr 保存底层的C++ 对象指针,为了后面反转成 C++ 对象,操作 C++ 对象功能, 是保存在 native 堆中的,不受 GC 的影响;
- Parcel.java
- android_os_Parcel.cpp 对应 java 类的包名
- Parcel.cpp
共享内存
Parcel翻译过来是打包的意思,其实就是包装了我们需要传输的数据,然后在Binder中传输,也就是用于跨进程传输数据共享内存
简单来说,Parcel提供了一套机制,可以将序列化之后的数据写入到一个共享内存中,其他进程通过Parcel可以从这块共享内存中读出字节流,并反序列化成对象, 下图是这个过程的模型。