Parcel
Parcel创建
构造方法私有。
静态方法Parcel#obtain和Parcel#obtain(long obj)创建。
public static Parcel obtain() {
final Parcel[] pool = sOwnedPool;
synchronized (pool) {
Parcel p;
for (int i=0;
i
sOwnedPool内部Parcel池,数组,可存储POOL_SIZE个Parcel,POOL_SIZE是6,从0开始遍历,找到数组中不空的位置,返回Parcel,置空该位置。
数组池中全空,新建Parcel对象返回。参数是0。
sOwnedPool池中存储的都是自己创建(nativeCreate)native层Parcel的Parcel,sHolderPool池存储的是传入native层指针的Parcel。
Parcel构造方法触发Parcel#init初始化。
private void init(long nativePtr) {
if (nativePtr != 0) {
mNativePtr = nativePtr;
mOwnsNativeParcelObject = false;
} else {
mNativePtr = nativeCreate();
mOwnsNativeParcelObject = true;
}
}
若nativePtr是0,JNI#nativeCreate创建native层Parcel对象,返回mNativePtr指针。若nativePtr非0,将其他Java层Parcel存储的native层指针赋值mNativePtr。
JNI#android_os_Parcel_create方法
static jlong android_os_Parcel_create(JNIEnv* env, jclass clazz)
{
Parcel* parcel = new Parcel();
return reinterpret_cast(parcel);
}
创建native层Parcel对象。
因此,Java层Parcel对象引用native层Parcel的指针。
Parcel#writeInt分析
Parcel#writeInt方法
public final void writeInt(int val) {
nativeWriteInt(mNativePtr, val);
}
触发JNI#nativeWriteInt方法。
static void android_os_Parcel_writeInt(JNIEnv* env, jclass clazz, jlong nativePtr, jint val) {
Parcel* parcel = reinterpret_cast(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeInt32(val);
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
native层Parcel对象,writeInt32会调用writeAligned方法。
status_t Parcel::writeAligned(T val) {
COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T));
if ((mDataPos+sizeof(val)) <= mDataCapacity) {
restart_write:
*reinterpret_cast(mData+mDataPos) = val;
return finishWrite(sizeof(val));
}
status_t err = growData(sizeof(val));
if (err == NO_ERROR) goto restart_write;
return err;
}
mData代表写入的初始地址值,字节类型指针。mDataPos为当前指向的地址值偏移量。val计算出占用几个字节。当mDataPos偏移量加上val字节数不大于mDataCapacity容量时,mDataPos偏移再加上mData,为放置val的地址,通过*取指向的内容,设置为val,最后finishWrite更新mDataPos自增val的字节大小。
若大于mDataCapacity,则growData扩容后restart_write重新设置。
综上,Parcel写入的数据存储在native内存空间。
回收Parcel
Parcel#recycle()
public final void recycle() {
freeBuffer();
final Parcel[] pool;
if (mOwnsNativeParcelObject) {//构造方法自己创建的底层,mNativePtr值不变。
pool = sOwnedPool;
//存入sOwnedPool数组池
} else {
mNativePtr = 0;
//本来就是传入的底层指针,设为0。
pool = sHolderPool;
}synchronized (pool) {
for (int i=0;
i
从0遍历每个数组元素,如果为空,则将数组该项设置调用者Parcel。
若是自己创建的底层,则freeBuffer释放。
JNI#nativeFreeBuffer方法
static void android_os_Parcel_freeBuffer(JNIEnv* env, jclass clazz, jlong nativePtr)
{
Parcel* parcel = reinterpret_cast(nativePtr);
if (parcel != NULL) {
parcel->freeData();
}
}
native层Parcel对象freeData方法。
【Parcel】任重而道远
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- django-前后端交互
- IDEA|IDEA 创建工程
- 创建缔造完美教室,让每一间教室都闪闪发光
- Servlet原理|Servlet原理 二(Web应用与创建Servlet实例)
- 企业为什么要融资
- 热点文章|鸢尾花预测(如何创建机器学习Web应用程序())
- 诚实表达,创建连接维护界限
- FTP创建
- 脚手架工具,Yeoman
- Python多线程编程——创建线程的两个方法