Android native CursorWindow数据保存原理
2017-06-10 15:43
323 查看
我们通过Uri查询数据库所得到的数据集,保存在native层的CursorWindow中。CursorWindow的实质是共享内存的抽象,以实现跨进程数据共享。共享内存所採用的实现方式是文件映射。
在ContentProvider端透过SQLiteDatabase的封装查询到的数据集保存在CursorWindow所指向的共享内存中。然后通过Binder把这片共享内存传递到ContentResolver端,即查询端。
这样客户就能够通过Cursor来訪问这块共享内存中的数据集了。
那么CursorWindow是怎样实现的呢?
1.通过Create静态函数来创建
2.通过文件句柄来创建。这样的case应该是在client的创建出一个CursorWindow所採用。
CursorWindow是怎样保存查询到的数据集的呢?
原理图例如以下:
没一行所相应的数据採用FieldSlot数组来表示。
图中黄色部分表示一行所相应的数据。假设列所相应的数据是long或者double。那么就直接保存在FieldSlot中,假设是Blob或者String,那么就在FieldSlot中保存数据的廉价量。
FiledSlot的定义例如以下:
在ContentProvider端透过SQLiteDatabase的封装查询到的数据集保存在CursorWindow所指向的共享内存中。然后通过Binder把这片共享内存传递到ContentResolver端,即查询端。
这样客户就能够通过Cursor来訪问这块共享内存中的数据集了。
那么CursorWindow是怎样实现的呢?
1.通过Create静态函数来创建
status_t CursorWindow::create(const String8& name, size_t size, CursorWindow** outCursorWindow) { String8 ashmemName("CursorWindow: "); ashmemName.append(name);//文件名称 status_t result; int ashmemFd = ashmem_create_region(ashmemName.string(), size); if (ashmemFd < 0) { result = -errno; } else { result = ashmem_set_prot_region(ashmemFd, PROT_READ | PROT_WRITE); if (result >= 0) { void* data = ::mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0);//文件映射 if (data == MAP_FAILED) { result = -errno; } else { result = ashmem_set_prot_region(ashmemFd, PROT_READ); if (result >= 0) { CursorWindow* window = new CursorWindow(name, ashmemFd, data, size, false /*readOnly*/); result = window->clear(); if (!result) { LOG_WINDOW("Created new CursorWindow: freeOffset=%d, " "numRows=%d, numColumns=%d, mSize=%d, mData=%p", window->mHeader->freeOffset, window->mHeader->numRows, window->mHeader->numColumns, window->mSize, window->mData); *outCursorWindow = window; return OK; } delete window; } } ::munmap(data, size); } ::close(ashmemFd); } *outCursorWindow = NULL; return result; }
2.通过文件句柄来创建。这样的case应该是在client的创建出一个CursorWindow所採用。
status_t CursorWindow::createFromParcel(Parcel* parcel, CursorWindow** outCursorWindow) { String8 name = parcel->readString8(); status_t result; int ashmemFd = parcel->readFileDescriptor(); if (ashmemFd == int(BAD_TYPE)) { result = BAD_TYPE; } else { ssize_t size = ashmem_get_size_region(ashmemFd); if (size < 0) { result = UNKNOWN_ERROR; } else { int dupAshmemFd = ::dup(ashmemFd); if (dupAshmemFd < 0) { result = -errno; } else { void* data = ::mmap(NULL, size, PROT_READ, MAP_SHARED, dupAshmemFd, 0); if (data == MAP_FAILED) { result = -errno; } else { CursorWindow* window = new CursorWindow(name, dupAshmemFd, data, size, true /*readOnly*/); LOG_WINDOW("Created CursorWindow from parcel: freeOffset=%d, " "numRows=%d, numColumns=%d, mSize=%d, mData=%p", window->mHeader->freeOffset, window->mHeader->numRows, window->mHeader->numColumns, window->mSize, window->mData); *outCursorWindow = window; return OK; } ::close(dupAshmemFd); } } } *outCursorWindow = NULL; return result; }
CursorWindow是怎样保存查询到的数据集的呢?
原理图例如以下:
没一行所相应的数据採用FieldSlot数组来表示。
图中黄色部分表示一行所相应的数据。假设列所相应的数据是long或者double。那么就直接保存在FieldSlot中,假设是Blob或者String,那么就在FieldSlot中保存数据的廉价量。
FiledSlot的定义例如以下:
struct FieldSlot { private: int32_t type;//列所相应的数据的类型 union { double d; int64_t l; struct { uint32_t offset; uint32_t size; } buffer; } data;//data的数据类型是union,当type所表示的是String或者Blob的时候。offset表示的就是保存真实数据的buffer的偏移量。size表示buffer的大小 friend class CursorWindow; } __attribute((packed));
相关文章推荐
- Android native CursorWindow数据保存原理
- Android native CursorWindow数据保存原理
- Android 数据的保存,检索,删除之Cursor
- sqlite在Android上的一个bug:SQLiteCantOpenDatabaseException when nativeExecuteForCursorWindow
- 【Android游戏开发十二】(保存游戏数据 [上文])详解SharedPreference 与 FIleInputStream/FileOutputStream将数据存储到SD卡中!
- 【Android游戏开发十二】(保存游戏数据 [上文])详解SharedPreference 与 FIleInputStream/FileOutputStream将数据存储到SD卡中!
- Android开发中保存数据的四种方法方法
- hibernate 数据保存操作方法的原理对比
- jsp hibernate 数据保存操作的原理
- android往文件中保存和读取数据
- Pfc核心:窗口数据的保存原理(暂缺)
- hibernate 数据保存操作的原理
- Android的关键的持久数据应该在onPause()方法中保存
- Android数据存储操作⑤Adapter之SimpleCursorAdapter
- android-sharedpreferences(数据的保存和读取)
- 【Android游戏开发十三】(保存游戏数据 [下文])详解SQLite存储方式,并把SQLite的数据库文件存储在SD卡中!!!
- Android四种保存数据的方法
- jsp hibernate 数据保存操作的原理
- Android--将数据保存到SDCard中
- 【Android游戏开发十三】(保存游戏数据 [下文])详解SQLite存储方式