探索Android中的Parcel机制.docx
- 文档编号:8422963
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:67
- 大小:59.99KB
探索Android中的Parcel机制.docx
《探索Android中的Parcel机制.docx》由会员分享,可在线阅读,更多相关《探索Android中的Parcel机制.docx(67页珍藏版)》请在冰豆网上搜索。
探索Android中的Parcel机制
探索Android中的Parcel机制(上)
一.先从Serialize说起
我们都知道JAVA中的Serialize机制,译成串行化、序列化……,其作用是能将数据对象存入字节流当中,在需要时重新生成对象。
主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等。
二.Android中的新的序列化机制
在Android系统中,定位为针对内存受限的设备,因此对性能要求更高,另外系统中采用了新的IPC(进程间通信)机制,必然要求使用性能更出色的对象传输方式。
在这样的环境下,Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。
三.Parcel类的背后
在Framework中有parcel类,源码路径是:
Frameworks/base/core/java/android/os/Parcel.java
典型的源码片断如下:
[java]viewplaincopyprint?
1./**
2. * Write an integer value into the parcel at the current dataPosition(),
3. * growing dataCapacity() if needed.
4. */
5.public final native void writeInt(int val);
6.
7./**
8. * Write a long integer value into the parcel at the current dataPosition(),
9. * growing dataCapacity() if needed.
10. */
11.public final native void writeLong(long val);
从中我们看到,从这个源程序文件中我们看不到真正的功能是如何实现的,必须透过JNI往下走了。
于是,Frameworks/base/core/jni/android_util_Binder.cpp中找到了线索
[java]viewplaincopyprint?
1.static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)
2.{
3. Parcel* parcel = parcelForJavaObject(env, clazz);
4. if (parcel !
= NULL) {
5. const status_t err = parcel->writeInt32(val);
6. if (err !
= NO_ERROR) {
7. jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
8. }
9. }
10.}
11.
12.static void android_os_Parcel_writeLong(JNIEnv* env, jobject clazz, jlong val)
13.{
14. Parcel* parcel = parcelForJavaObject(env, clazz);
15. if (parcel !
= NULL) {
16. const status_t err = parcel->writeInt64(val);
17. if (err !
= NO_ERROR) {
18. jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
19. }
20. }
21.}
从这里我们可以得到的信息是函数的实现依赖于Parcel指针,因此还需要找到Parcel的类定义,注意,这里的类已经是用C++语言实现的了。
找到Frameworks/base/include/binder/parcel.h和Frameworks/base/libs/binder/parcel.cpp。
终于找到了最终的实现代码了。
有兴趣的朋友可以自己读一下,不难理解,这里把基本的思路总结一下:
1. 整个读写全是在内存中进行,主要是通过malloc()、realloc()、memcpy()等内存操作进行,所以效率比JAVA序列化中使用外部存储器会高很多;
2. 读写时是4字节对齐的,可以看到#definePAD_SIZE(s)(((s)+3)&~3)这句宏定义就是在做这件事情;
3. 如果预分配的空间不够时newSize=((mDataSize+len)*3)/2;会一次多分配50%;
4. 对于普通数据,使用的是mData内存地址,对于IBinder类型的数据以及FileDescriptor使用的是mObjects内存地址。
后者是通过flatten_binder()和unflatten_binder()实现的,目的是反序列化时读出的对象就是原对象而不用重新new一个新对象。
好了,这就是Parcel背后的动作,全是在一块内存里进行读写操作,就不啰嗦了,把parcel的代码贴在这供没有源码的朋友参考吧。
接下来我会用一个小DEMO演示一下Parcel类在应用程序中的使用,详见《探索Android中的Parcel机制(下)》。
[cpp]viewplaincopyprint?
1./*
2. * Copyright (C) 2005 The Android Open Source Project
3. *
4. * Licensed under the Apache License, Version 2.0 (the "License");
5. * you may not use this file except in compliance with the License.
6. * You may obtain a copy of the License at
7. *
8. * http:
//www.apache.org/licenses/LICENSE-2.0
9. *
10. * Unless required by applicable law or agreed to in writing, software
11. * distributed under the License is distributed on an "AS IS" BASIS,
12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13. * See the License for the specific language governing permissions and
14. * limitations under the License.
15. */
16.
17. status_t setDataCapacity(size_t size);
18.
19. status_t setData(const uint8_t* buffer, size_t len);
20.
21. status_t appendFrom(Parcel *parcel, size_t start, size_t len);
22.
23. bool hasFileDescriptors() const;
24.
25. status_t writeInterfaceToken(const String16& interface);
26. bool enforceInterface(const String16& interface) const;
27. bool checkInterface(IBinder*) const;
28.
29. void freeData();
30.
31. const size_t* objects() const;
32. size_t objectsCount() const;
33.
34. status_t errorCheck() const;
35. void setError(status_t err);
36.
37. status_t write(const void* data, size_t len);
38. void* writeInplace(size_t len);
39. status_t writeUnpadded(const void* data, size_t len);
40. status_t writeInt32(int32_t val);
41. status_t writeInt64(int64_t val);
42. status_t writeFloat(float val);
43. status_t writeDouble(double val);
44. status_t writeIntPtr(intptr_t val);
45. status_t writeCString(const char* str);
46. status_t writeString8(const String8& str);
47. status_t writeString16(const String16& str);
48. status_t writeString16(const char16_t* str, size_t len);
49. status_t writeStrongBinder(const sp
50. status_t writeWeakBinder(const wp
51. status_t write(const Flattenable& val);
52.
53. // Place a native_handle into the parcel (the native_handle's file-
54. // descriptors are dup'ed, so it is safe to delete the native_handle
55. // when this function returns).
56. // Doesn't take ownership of the native_handle.
57. status_t writeNativeHandle(const native_handle* handle);
58.
59. // Place a file descriptor into the parcel. The given fd must remain
60. // valid for the lifetime of the parcel.
61. status_t writeFileDescriptor(int fd);
62.
63. // Place a file descriptor into the parcel. A dup of the fd is made, which
64. // will be closed once the parcel is destroyed.
65. status_t writeDupFileDescriptor(int fd);
66.
67. status_t writeObject(const flat_binder_object& val, bool nullMetaData);
68.
69. void remove(size_t start, size_t amt);
70.
71. status_t read(void* outData, size_t len) const;
72. const void* readInplace(size_t len) const;
73. int32_t readInt32() const;
74. status_t readInt32(int32_t *pArg) const;
75. int64_t readInt64() const;
76. status_t readInt64(int64_t *pArg) const;
77. float readFloat() const;
78. status_t readFloat(float *pArg) const;
79. double readDouble() const;
80. status_t readDouble(double *pArg) const;
81. intptr_t readIntPtr() const;
82. status_t readIntPtr(intptr_t *pArg) const;
83.
84. const char* readCString() const;
85. String8 readString8() const;
86. String16 readString16() const;
87. const char16_t* readString16Inplace(size_t* outLen) const;
88. sp
89. wp
90. status_t read(Flattenable& val) const;
91.
92. // Retrieve native_handle from the parcel. This returns a copy of the
93. // parcel's native_handle (the caller takes ownership). The caller
94. // must free the native_handle with native_handle_close() and
95. // native_handle_delete().
96. native_handle* readNativeHandle() const;
97.
98.
99. // Retrieve a file descriptor from the parcel. This returns the raw fd
100. // in the parcel, which you do not own -- use dup() to get your own copy.
101. int readFileDescriptor() const;
102.
103. const flat_binder_object* readObject(bool nullMetaData) const;
104.
105. // Explicitly close all file descriptors in the parcel.
106. void closeFileDescriptors();
107.
108. typedef void (*release_func)(Parcel* parcel,
109. const uint8_t* data, size_t dataSize,
110. const size_t* objects, size_t objectsSize,
111. void* cookie);
112.
113. const uint8_t* ipcData() const;
114. size_t ipcDataSize() const;
115. const size_t* ipcObjects() const;
116. size_t ipcObjectsCount() const;
117. void ipcSetDataReference(const uint8_t* data, size_t dataSize,
118. const size_t* objects, size_t objectsCount,
119. release_func relFunc, void* relCookie);
120.
121. void print(TextOutput& to, uint32_t flags = 0) const;
122.
123.private:
124. Parcel(const Parcel& o);
125. Parcel& operator=(const Parcel& o);
126.
127. status_t finishWrite(size_t len);
128. void releaseObjects();
129. void acquireObjects();
130. status_t growData(size_t len);
131. status_t restartWrite(size_t desired);
132. status_t continueWrite(size_t desired);
133. void freeDataNoInit();
134. void initState();
135. void scanForFds() const;
136.
137. template
138. status_t readAligned(T *pArg) const;
139.
140. template
141.
142. template
143. status_t writeAligned(T val);
144.
145. status_t mError;
146. uint8_t* mData;
147. size_t mDataSize;
148. size_t mDataCapacity;
149. mutable size_t mDataPos;
150. size_t* mObjects;
151. size_t mObjectsSize;
152. size_t mObjectsCapacity;
153. muta
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 探索 Android 中的 Parcel 机制