员工年度工作总结报告(2012年度)--张宝华
???一.先从Serialize说起
? ?? ? 我们都知道JAVA中的Serialize机制,译成串行化、序列化……,其作用是能将数据对象存入字节流当中,在需要时重新生成对象。主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等。
? ?? ??二.Android中的新的序列化机制
? ?? ? 在Android系统中,定位为针对内存受限的设备,因此对性能要求更高,另外系统中采用了新的IPC(进程间通信)机制,必然要求使用性能更出色的对象传输方式。在这样的环境下,Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。
? ?? ??三.Parcel类的背后
? ?? ? 在Framework中有parcel类,源码路径是:Frameworks/base/core/java/android/os/Parcel.java
? ?? ? 典型的源码片断如下:
java代码:
- finishWrite(padded);
- return data;
- }?
- status_t err = growData(padded);
- if (err == NO_ERROR) goto restart_write;
- return NULL;
- }?
- status_t Parcel::writeInt32(int32_t val)
- {
- return writeAligned(val);
- }?
- status_t Parcel::writeInt64(int64_t val)
- {
- return writeAligned(val);
- }?
- status_t Parcel::writeFloat(float val)
- {
- return writeAligned(val);
- }?
- status_t Parcel::writeDouble(double val)
- {
- return writeAligned(val);
- }?
- status_t Parcel::writeIntPtr(intptr_t val)
- {
- return writeAligned(val);
- }?
- status_t Parcel::writeCString(const char* str)
- {
- return write(str, strlen(str)+1);
- }?
- status_t Parcel::writeString8(const String8& str)
- {
- status_t err = writeInt32(str.bytes());
- if (err == NO_ERROR) {
- err = write(str.string(), str.bytes()+1);
- }
- return err;
- }?
- status_t Parcel::writeString16(const String16& str)
- {
- return writeString16(str.string(), str.size());
- }?
- status_t Parcel::writeString16(const char16_t* str, size_t len)
- {
- if (str == NULL) return writeInt32(-1);?
- status_t err = writeInt32(len);
- if (err == NO_ERROR) {
- len *= sizeof(char16_t);
- uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char16_t));
- if (data) {
- memcpy(data, str, len);
- *reinterpret_cast(data+len) = 0;
- return NO_ERROR;
- }
- err = mError;
- }
- return err;
- }?
- status_t Parcel::writeStrongBinder(const sp& val)
- {
- return flatten_binder(ProcessState::self(), val, this);
- }?
- status_t Parcel::writeWeakBinder(const wp& val)
- {
- return flatten_binder(ProcessState::self(), val, this);
- }?
- status_t Parcel::writeNativeHandle(const native_handle* handle)
- {
- if (!handle || handle->version != sizeof(native_handle))
- return BAD_TYPE;?
- status_t err;
- err = writeInt32(handle->numFds);
- if (err != NO_ERROR) return err;?
- err = writeInt32(handle->numInts);
- if (err != NO_ERROR) return err;?
- for (int i=0 ; err==NO_ERROR && inumFds ; i++)
- err = writeDupFileDescriptor(handle->data[i]);?
- if (err != NO_ERROR) {
- LOGD(“write native handle, write dup fd failed”);
- return err;
- }
- err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
- return err;
- }?
- status_t Parcel::writeFileDescriptor(int fd)
- {
- flat_binder_object obj;
- obj.type = BINDER_TYPE_FD;
- obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
- obj.handle = fd;
- obj.cookie = (void*)0;
- return writeObject(obj, true);
- }?
- status_t Parcel::writeDupFileDescriptor(int fd)
- {
- flat_binder_object obj;
- obj.type = BINDER_TYPE_FD;
- obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
- obj.handle = dup(fd);
- obj.cookie = (void*)1;
- return writeObject(obj, true);
- }?
- status_t Parcel::write(const Flattenable& val)
- {
- status_t err;?
- // size if needed
- size_t len = val.getFlattenedSize();
- size_t fd_count = val.getFdCount();?
- err = this->writeInt32(len);
- if (err) return err;?
- err = this->writeInt32(fd_count);
- if (err) return err;?
- // payload
- void* buf = this->writeInplace(PAD_SIZE(len));
- if (buf == NULL)
- return BAD_VALUE;?
- int* fds = NULL;
- if (fd_count) {
- fds = new int[fd_count];
- }?
- err = val.flatten(buf, len, fds, fd_count);
- for (size_t i=0 ; i err = this->writeDupFileDescriptor( fds[i] );
- }?
- if (fd_count) {
- delete [] fds;
- }?
- return err;
- }?
- status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
- {
- const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
- const bool enoughObjects = mObjectsSize < mObjectsCapacity;
- if (enoughData && enoughObjects) {
- restart_write:
- *reinterpret_cast(mData+mDataPos) = val;?
- // Need to write meta-data?
- if (nullMetaData || val.binder != NULL) {
- mObjects[mObjectsSize] = mDataPos;
- acquire_object(ProcessState::self(), val, this);
- mObjectsSize++;
- }?
- // remember if it’s a file descriptor
- if (val.type == BINDER_TYPE_FD) {
- mHasFds = mFdsKnown = true;
- }?
- return finishWrite(sizeof(flat_binder_object));
- }?
- if (!enoughData) {
- const status_t err = growData(sizeof(val));
- if (err != NO_ERROR) return err;
- }
- if (!enoughObjects) {
- size_t newSize = ((mObjectsSize+2)*3)/2;
- size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
- if (objects == NULL) return NO_MEMORY;
- mObjects = objects;
- mObjectsCapacity = newSize;
- }?