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>() {
@Override
public ApiResponseBean createFromParcel(Parcel in) {
return new ApiResponseBean(in);
}
@Override
public ApiResponseBean[] newArray(int size) {
return new ApiResponseBean[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public 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.
*/
@NonNull
public 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 used
if (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可以从这块共享内存中读出字节流,并反序列化成对象, 下图是这个过程的模型。