Android 开发中Parcel存储类型和数据容器

jopen 13年前
     <span style="font-family:'Times New Roman';font-size:10.5pt;">在<span style="font-family:Times New Roman;">android</span><span style="font-family:宋体;">中使用</span><span style="font-family:Times New Roman;">Parcel</span><span style="font-family:宋体;">(存储基本数据类型和引用数据类型的容器)通过</span><span style="font-family:Times New Roman;">IBinder</span><span style="font-family:宋体;">来绑定,这种方法的作用是让数据在进程间传递数据,</span><span style="font-family:Times New Roman;">Parcel</span><span style="font-family:宋体;">定位就是轻量级的高效的对象序列化和反序列化机制。</span></span>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">在<span style="font-family:Times New Roman;">Framework</span><span style="font-family:宋体;">中有</span><span style="font-family:Times New Roman;">parcel</span><span style="font-family:宋体;">类,源码路径是:</span></span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">Frameworks/base/core/java/android/os/Parcel.java</span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">典型的源码片断如下:</span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"></p>    <pre class="brush:java; toolbar: true; auto-links: false;">/  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); </pre>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">他的方法如下:</span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">Parcel parcel = Parcel.obtain();// </span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">获取一个<span style="font-family:Times New Roman;">Parcel </span><span style="font-family:宋体;">对象下面就可以对其进行方法进行操作了,</span></span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">createXXX(),wirteXXX(),readXXX(),</span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">其中<span style="font-family:Times New Roman;">dataPosition(),</span><span style="font-family:宋体;">返回当前</span><span style="font-family:Times New Roman;">Parcel</span><span style="font-family:宋体;">当前对象存储数据的偏移量,而</span><span style="font-family:Times New Roman;">setDataPosition(),</span><span style="font-family:宋体;">设置当前</span><span style="font-family:Times New Roman;">Parcel</span><span style="font-family:宋体;">对象的偏移量,方便读取</span><span style="font-family:Times New Roman;">parcel</span><span style="font-family:宋体;">中的数据,可问题就出在我读取出来的数据要么是空(</span><span style="font-family:Times New Roman;">null</span><span style="font-family:宋体;">)</span><span style="font-family:Times New Roman;">,</span><span style="font-family:宋体;">要么永远是第一个偏移量处的值。</span><span style="font-family:Times New Roman;">Parcel</span><span style="font-family:宋体;">采用什么机制实现的,是以什么形式的存储的,然后我才能任意对其操作。</span></span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">基本数据类型的取值范围,<span style="font-family:Times New Roman;">boolean 1bit</span><span style="font-family:宋体;">、</span><span style="font-family:Times New Roman;">short 16bit</span><span style="font-family:宋体;">、</span><span style="font-family:Times New Roman;">int 32bit</span><span style="font-family:宋体;">、</span><span style="font-family:Times New Roman;">long 64bit</span><span style="font-family:宋体;">、</span><span style="font-family:Times New Roman;">float 32bit</span><span style="font-family:宋体;">、</span><span style="font-family:Times New Roman;">double 64bit</span><span style="font-family:宋体;">、</span><span style="font-family:Times New Roman;">char 16bit</span><span style="font-family:宋体;">、</span><span style="font-family:Times New Roman;">byte 8bit</span></span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">由此我可以猜想,<span style="font-family:Times New Roman;">Parcel 32bit </span><span style="font-family:宋体;">作为基本单位存储写入的变量</span><span style="font-family:Times New Roman;">,4byte*8=32bit,</span><span style="font-family:宋体;">在内存中的引用地址变量是采用</span><span style="font-family:Times New Roman;">16</span><span style="font-family:宋体;">进制进行编码,且作为偏移量,即偏移量是</span><span style="font-family:Times New Roman;">4</span><span style="font-family:宋体;">的倍数,</span><span style="font-family:Times New Roman;">0,4,8,12,16,20,24,28,32,36,40,44,48……4*N,f(x) = 4*y</span><span style="font-family:宋体;">{</span><span style="font-family:Times New Roman;">y>=0&y</span><span style="font-family:宋体;">是自然数}</span></span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">我想绝对不会出现向偏移量是<span style="font-family:Times New Roman;">3</span><span style="font-family:宋体;">,</span><span style="font-family:Times New Roman;">6</span><span style="font-family:宋体;">,</span><span style="font-family:Times New Roman;">9</span><span style="font-family:宋体;">这样的数据。。。由此我们可以推断出,无论他存储的是基本数据类型或引用数据类型的变量,都是以</span><span style="font-family:Times New Roman;">32bit</span><span style="font-family:宋体;">基本单位作为偏移量。</span></span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">parcel.writeInt(1);parcel.writeInt(2);parcel.writeInt(3);parcel.writeInt(4);parcel.writeInt(5);parcel.writeInt(6);parcel.writeInt(7);parcel.writeInt(81011111);parcel.writeFloat(1f);parcel.writeFloat(1000000000000000000000000000000000000f);parcel.writeXXX(),<span style="font-family:宋体;">每写一次数据,在</span><span style="font-family:Times New Roman;">32bit</span><span style="font-family:宋体;">的空间里能够存储要放入的变量,怎只占一个偏移量,也就之一动</span><span style="font-family:Times New Roman;">4</span><span style="font-family:宋体;">个位置。</span></span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">而当存储的数据如:<span style="font-family:Times New Roman;">parcel.writeFloat(1000000000000000000000000000000000000f);</span><span style="font-family:宋体;">他就自动往后移动,</span></span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">parcel.writeString(“a”);parcel.writeString(“b”);parcel.writeString(“d”);parcel.writeString(“c”);<span style="font-family:宋体;">和</span><span style="font-family:Times New Roman;">parcel.writeString(“abcd”); </span><span style="font-family:宋体;">的区别。</span></span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">有此可见,他的内存的分配原来是这样的。那我怎样才能把我存进去的数据依次的去出来呢?<span style="font-family:Times New Roman;">setDataPosition(),</span><span style="font-family:宋体;">设置</span><span style="font-family:Times New Roman;">parcel</span><span style="font-family:宋体;">的偏移量,在</span><span style="font-family:Times New Roman;">readXXX(),</span><span style="font-family:宋体;">读取数据</span></span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"></p>    <pre class="brush:java; toolbar: true; auto-links: false;">int size = parcel.dataSize();  int i = 0;  while (i <= size )   {  parcel.setDataPosition(i);  int curr_int = parcel.readInt();  i+=4;  int j = 0;  j++;  }</pre>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"><span style="font-family:'Times New Roman';font-size:10.5pt;">由此可见<span style="font-family:Times New Roman;">parcel</span><span style="font-family:宋体;">写入数据是按照</span><span style="font-family:Times New Roman;">32bit </span><span style="font-family:宋体;">为基本的容器,依次存储写入的数据,基本和引用(其实引用的也是有多个基本数据类型组合而成</span><span style="font-family:Times New Roman;">OBJECTS</span><span style="font-family:宋体;">-属性|方法),读取的时候我们就可以按照这种规律根据目标数据的偏移量的位置(</span><span style="font-family:Times New Roman;">curr_position</span><span style="font-family:宋体;">),以及偏移量的大小</span><span style="font-family:Times New Roman;">(size)</span><span style="font-family:宋体;">,取出已经存进去的数据了。</span></span></p>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"></p>    <pre class="brush:java; toolbar: true; auto-links: false;">int i = curr_position;  while (i <= size )  {  parcel.setDataPosition(i);  int curr_int = parcel.readXXXt();  i+=4;  int j = 0;  j++;  }</pre>    <p style="margin-top:0pt;margin-bottom:0pt;" class="p0"></p>    <span style="font-family:'宋体';font-size:10.5pt;">最后提醒一句</span>    <span style="font-family:'Times New Roman';font-size:10.5pt;">,</span>    <span style="font-family:'宋体';font-size:10.5pt;">在</span>    <span style="font-family:'Times New Roman';font-size:10.5pt;">java<span style="font-family:宋体;">中基本数据类型的取值范围,引用类型的数据,相当于</span><span style="font-family:Times New Roman;">c</span><span style="font-family:宋体;">中的指针,以及各进制之间的相互转换和灵活的引用,以及定制自己想要的任意进制数据类型。</span></span>    <span style="font-family:'Times New Roman';font-size:10.5pt;">译成串行化、序列化<span style="font-family:Times New Roman;">……</span><span style="font-family:宋体;">,其作用是能将数据对象存入字节流当中,在需要时重新生成对象。主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等。</span></span>    <span style="font-family:'Times New Roman';font-size:10.5pt;"> </span>