Android native CursorWindow数据保存原理

转载 2017年01月03日 14:33:51

转自http://blog.csdn.net/ifloveelse/article/details/28394103



我们通过Uri查询数据库所得到的数据集,保存在native层的CursorWindow中。CursorWindow的实质是共享内存的抽象,以实现跨进程数据共享。共享内存所采用的实现方式是文件映射。

在ContentProvider端透过SQLiteDatabase的封装查询到的数据集保存在CursorWindow所指向的共享内存中,然后通过Binder把这片共享内存传递到ContentResolver端,即查询端。这样客户就可以通过Cursor来访问这块共享内存中的数据集了。

那么CursorWindow是如何实现的呢?

1.通过Create静态函数来创建

  1. status_t CursorWindow::create(const String8& name, size_t size, CursorWindow** outCursorWindow) {  
  2.     String8 ashmemName("CursorWindow: ");  
  3.     ashmemName.append(name);//文件名  
  4.   
  5.     status_t result;  
  6.     int ashmemFd = ashmem_create_region(ashmemName.string(), size);  
  7.     if (ashmemFd < 0) {  
  8.         result = -errno;  
  9.     } else {  
  10.         result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE);  
  11.         if (result >= 0) {  
  12.             void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);//文件映射  
  13.             if (data == MAP_FAILED) {  
  14.                 result = -errno;  
  15.             } else {  
  16.                 result = ashmem_set_prot_region(ashmemFd, PROT_READ);  
  17.                 if (result >= 0) {  
  18.                     CursorWindow* window = new CursorWindow(name, ashmemFd,  
  19.                             data, size, false /*readOnly*/);  
  20.                     result = window->clear();  
  21.                     if (!result) {  
  22.                         LOG_WINDOW("Created new CursorWindow: freeOffset=%d, "  
  23.                                 "numRows=%d, numColumns=%d, mSize=%d, mData=%p",  
  24.                                 window->mHeader->freeOffset,  
  25.                                 window->mHeader->numRows,  
  26.                                 window->mHeader->numColumns,  
  27.                                 window->mSize, window->mData);  
  28.                         *outCursorWindow = window;  
  29.                         return OK;  
  30.                     }  
  31.                     delete window;  
  32.                 }  
  33.             }  
  34.             ::munmap(data, size);  
  35.         }  
  36.         ::close(ashmemFd);  
  37.     }  
  38.     *outCursorWindow = NULL;  
  39.     return result;  
  40. }  

2.通过文件句柄来创建。这种case应该是在客户端的创建出一个CursorWindow所采用。

  1. status_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow) {  
  2.     String8 name = parcel->readString8();  
  3.   
  4.     status_t result;  
  5.     int ashmemFd = parcel->readFileDescriptor();  
  6.     if (ashmemFd == int(BAD_TYPE)) {  
  7.         result = BAD_TYPE;  
  8.     } else {  
  9.         ssize_t size = ashmem_get_size_region(ashmemFd);  
  10.         if (size < 0) {  
  11.             result = UNKNOWN_ERROR;  
  12.         } else {  
  13.             int dupAshmemFd = ::dup(ashmemFd);  
  14.             if (dupAshmemFd < 0) {  
  15.                 result = -errno;  
  16.             } else {  
  17.                 void* data = ::mmap(NULL, size, PROT_READ, MAP_SHARED, dupAshmemFd, 0);  
  18.                 if (data == MAP_FAILED) {  
  19.                     result = -errno;  
  20.                 } else {  
  21.                     CursorWindow* window = new CursorWindow(name, dupAshmemFd,  
  22.                             data, size, true /*readOnly*/);  
  23.                     LOG_WINDOW("Created CursorWindow from parcel: freeOffset=%d, "  
  24.                             "numRows=%d, numColumns=%d, mSize=%d, mData=%p",  
  25.                             window->mHeader->freeOffset,  
  26.                             window->mHeader->numRows,  
  27.                             window->mHeader->numColumns,  
  28.                             window->mSize, window->mData);  
  29.                     *outCursorWindow = window;  
  30.                     return OK;  
  31.                 }  
  32.                 ::close(dupAshmemFd);  
  33.             }  
  34.         }  
  35.     }  
  36.     *outCursorWindow = NULL;  
  37.     return result;  
  38. }  

CursorWindow是如何保存查询到的数据集的呢?

原理图如下:

没一行所对应的数据采用FieldSlot数组来表示。图中黄色部分表示一行所对应的数据。如果列所对应的数据是long或者double,那么就直接保存在FieldSlot中,如果是Blob或者String,那么就在FieldSlot中保存数据的便宜量。

FiledSlot的定义如下:

  1. struct FieldSlot {  
  2. private:  
  3.     int32_t type;//列所对应的数据的类型  
  4.     union {  
  5.         double d;  
  6.         int64_t l;  
  7.         struct {  
  8.             uint32_t offset;  
  9.             uint32_t size;  
  10.         } buffer;  
  11.     } data;//data的数据类型是union,当type所表示的是String或者Blob的时候,offset表示的就是保存真实数据的buffer的偏移量,size表示buffer的大小  
  12.   
  13.     friend class CursorWindow;  
  14. } __attribute((packed)); 

相关文章推荐

Concepts of Cursor and CursorWindow on android platform

简记android平台下ContenProvider使用SQLite数据库实现时的代码片段和逻辑结构,主要描述Cursor和CursorWindow. Cursor can be treated a...

从源码看ANDROID中SQLITE是怎么通过CURSORWINDOW读DB的

从源码看ANDROID中SQLITE是怎么通过CURSORWINDOW读DB

AIR Native Extension on Android - Hello World(2) 结构及原理

转载: http://sswilliam.blog.163.com/blog/static/189696383201191095759867/ NativeExtension结构及原理 ...

React native for Android [原理剖析]

转自:http://blog.csdn.net/h416756139/article/details/51565069 摘要: Facebook 于2015年9月15日推出rea...

Android中在native层对java层应用程序发送广播方法及原理

Android中在native层对java层应用程序发送广播方法及原理详解Android从native发送数据给上层应用接收,常用的有JNI的形式,同样用广播也可以实现,本文正是基于广播实现nativ...

Android native应用开发简明教程 (2) - 本地应用的原理

本地App,本质上是一个Java App调用了一个JNI的库,而应用的逻辑通过native代码来实现。...
  • lusing
  • lusing
  • 2017年03月01日 11:57
  • 318

菜鸟学习React Native for Android 之通讯原理分析(JAVA调用JS)

主要参考自:React Native通讯原理:http://www.jianshu.com/p/17d6f6c57a5c 1.通讯框架图 2.Native调用JS Native调用JS流程分析: ...

React-Native 与 Android 集成 <三、原理与总结>

原文:腾讯Bugly(http://bugly.qq.com) ReactNative 让开发者使用 JavaScript 和 React 编写应用,利用相同的核心代码就可以创建 基于W...

React Native Android的启动白屏/闪屏的原因,解决方案,原理,使用方法

React Native Android启动屏,启动白屏,闪现白屏本文出自《React Native学习笔记》@http://www.cboy.me/系列文章。问题描述:用React Native架构...

王家林最受欢迎的一站式云计算大数据和移动互联网解决方案课程 V1(20140809)之Android软硬整合设计与框架揭秘: HAL&Framework &Native Service &App&HT

掌握Android从底层开发到框架整合技术到上层App开发及HTML5的全部技术; 一次彻底的Android架构、思想和实战技术的洗礼; 彻底掌握Andorid HAL、Android Runti...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android native CursorWindow数据保存原理
举报原因:
原因补充:

(最多只允许输入30个字)