Android教程:Parcelable 序列化操作数据
Android教程:Parcelable 序列化操作数据
序列化数据原理:
序列化的过程就是对象写入字节流和从字节流中读取对象。将对象状态转换成字节流之后,可以用java.io包中的各种字节流类将其保存到文件中,管道到另一线程中或通过网络连接将对象数据发送到另一主机。
简单说就是将数据对象存入字节流当中,在需要时重新生成对象。
Android中的序列化机制:
首先android系统利用Binder进行IPC通讯,且定位为针对内存受限的设备,所以则要求使用高效的对象传输方式,因为Parcel应运而生。
代码分析:
frameworks\base\core\java\android\os\Parcel.java
frameworks\base\core\jni\android_util_Binder.cpp JNI函数
以典型代码片段举例:
- /**
- * Write an integer value into the parcel at the current dataPosition(),
- * growing dataCapacity() if needed.
- */
- public final native void writeInt(int val);
- /**
- * Write a long integer value into the parcel at the current dataPosition(),
- * growing dataCapacity() if needed.
- */
- public final native void writeLong(long val);
- /**
- * Write a floating point value into the parcel at the current
- * dataPosition(), growing dataCapacity() if needed.
- */
- public final native void writeFloat(float val);
JNI层实现:
- static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
- {
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->writeInt32(val);
- if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
- }
- }
- }
- static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
- {
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->writeInt64(val);
- if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
- }
- }
- }
- static void android_os_Parcel_writeFloat(JNIEnv* env, jobject clazz, jfloat val)
- {
- Parcel* parcel = parcelForJavaObject(env, clazz);
- if (parcel != NULL) {
- const status_t err = parcel->writeFloat(val);
- if (err != NO_ERROR) {
- jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
- }
- }
- }
其本质使用 Parcel 对象来完成的,实现代码在:frameworks/base/libs/binder/parcel.cpp
- status_t Parcel::writeInt32(int32_t val)
- {
- return writeAligned(val);
- }
- --> 直接利用模块实现
- template<class T>
- status_t Parcel::writeAligned(T val) {
- COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T));
- if ((mDataPos+sizeof(val)) <= mDataCapacity) {
- restart_write:
- *reinterpret_cast<T*>(mData+mDataPos) = val; // 直接在此将数据写入到内存中
- return finishWrite(sizeof(val));
- }
- status_t err = growData(sizeof(val)); // 数据空间不够的情况下处理
- if (err == NO_ERROR) goto restart_write;
- return err;
- }
- status_t Parcel::growData(size_t len)
- {
- size_t newSize = ((mDataSize+len)*3)/2; // 每次多分配50%的内存空间
- return (newSize <= mDataSize)
- ? (status_t) NO_MEMORY
- : continueWrite(newSize);
- }
|
评论暂时关闭