• 探索Android中的Parcel机制(上)


    一.先从Serialize说起

             我们都知道JAVA中的Serialize机制,译成串行化、序列化……,其作用是能将数据对象存入字节流其中,在须要时又一次生成对象。主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等。

     

    二.Android中的新的序列化机制

             Android系统中,定位为针对内存受限的设备,因此对性能要求更高,另外系统中採用了新的IPC(进程间通信)机制,必定要求使用性能更出色的对象传输方式。在这种环境下,Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。

     

    三.Parcel类的背后

             Framework中有parcel类,源代码路径是:

    Frameworks/base/core/java/android/os/Parcel.java

    典型的源代码片断例如以下:

     

     

      

             从中我们看到,从这个源程序文件里我们看不到真正的功能是怎样实现的,必须透过JNI往下走了。于是,Frameworks/base/core/jni/android_util_Binder.cpp中找到了线索

     

      

             从这里我们能够得到的信息是函数的实现依赖于Parcel指针,因此还须要找到Parcel的类定义,注意,这里的类已经是用C++语言实现的了。

             找到Frameworks/base/include/binder/parcel.hFrameworks/base/libs/binder/parcel.cpp。最终找到了最终的实现代码了。

             有兴趣的朋友能够自己读一下,不难理解,这里把主要的思路总结一下:

    1.       整个读写全是在内存中进行,主要是通过malloc()realloc()memcpy()等内存操作进行,所以效率比JAVA序列化中使用外部存储器会高非常多;

    2.       读写时是4字节对齐的,能够看到#define PAD_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机制(下)》。

     

     

     

             本文的源代码使用的是Android 2.1版本号。

     

    ——欢迎转载,请注明出处 http://blog.csdn.net/caowenbin ——

     

  • 相关阅读:
    Linux中find命令用法全汇总,看完就没有不会用的!
    ubuntu16.04 通过命令,修改屏幕分辨率
    Linux下如何查看哪些进程占用的CPU内存资源最多
    shell脚本 在后台执行de 命令 >> 文件 2>&1 将标准输出与错误输出共同写入到文件中(追加到原有内容的后面)
    ef linq 访问视图返回结果重复
    asp.net core web 本地iis开发
    jQuery控制TR显示隐藏
    mvc EF 从数据库更新实体,添加视图实体时添加不上的问题
    无法确定依赖操作的有效顺序。由于外键约束、模型要求或存储生成的值,因此可能存在依赖关系
    还原差异备份——因为没有文件可用于前滚
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4544392.html
Copyright © 2020-2023  润新知