Android native CursorWindow数据保存原理
我们通过Uri查询数据库所得到的数据集,保存在native层的CursorWindow中。CursorWindow的实质是共享内存的抽象,以实现跨进程数据共享。共享内存所採用的实现方式是文件映射。
在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是怎样保存查询到的数据集的呢?
原理图例如以下:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU2FpbGluZ3RoaW5r/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
没一行所相应的数据採用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内存泄漏检测原理解析
转载请注明出处:https://www.cnblogs.com/zzcperf/articles/11615655.html 上一篇文章列举了不同版本Android OS内存泄漏的检测操作(传送门), ...
- Android中的数据保存
形式 Android的数据保存分为3种形式:file, SharedPreference, Database 文件 主要思想就是通过Context类中提供的openFileInput和openFile ...
- React-Native系列Android——Native与Javascript通信原理(一)
React-Native最核心的是Native与Javascript之间的通信,并且是双向通信.Native层到Javascript层,Javascript层到Native层.虽说是两个方向,但实现上 ...
- android中Json数据保存方式
package com.example.savejsonproject; import java.io.File; import java.io.FileNotFoundException; impo ...
- Android数据保存之SharedPreference
前言: 程序中处理的大部分问题都与数据有关,读取数据显示在UI上,读取的数据可以是本地的,也可以是网络的.保存用户数据到存储空间,可以是本地的数据库,文件等,也可以是保存到网络服务器.总之大部分的程序 ...
- Android应用程序组件Content Provider在应用程序之间共享数据的原理分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6967204 在Android系统中,不同的应用 ...
- Android Native -- Message/Handler/Looper机制(原理篇)
⌈Android Native消息队列处理系列文章⌋ Android Native -- Message/Handler/Looper机制(原理篇) Android Native -- Message ...
- Android少量数据保存之SharedPreferences接口实例
SharedPreferences数据保存主要是通过键值的方式存储在xml文件中 xml文件在data/此程序的包名/XX.xml 格式 <?xml version='1.0' encoding ...
- Android数据存储(1)少量数据保存之SharedPreferences接口实例
SharedPreferences数据保存主要是通过键值的方式存储在xml文件中 xml文件在data/此程序的包名/XX.xml 格式 <?xml version='1.0' encoding ...
随机推荐
- Android error--No implementation found for native Lcomd
在利用NDK编译Cpp执行时,出现了No implementation found for native Lcom等错误,调试好久,才发现 XXX.h和XXX.cpp.在XXX.cpp里#includ ...
- USACO 2.1 Ordered Fractions
Ordered Fractions Consider the set of all reduced fractions between 0 and 1 inclusive with denominat ...
- POJ 3260 DP
只需要对John的付款数做一次多重背包,对shopkeeper的找零钱数做一次完全背包即可. 最重要的是上界的处理.可以注意到,John的付款数最多为maxv*maxv+m,也就是24400元.同理, ...
- CodeFirst模式,容易引发数据迁移问题(不建议使用)
code first 模式 .模型类需要数据契约绑定[DataContract] .模型参数需要[DataMember]-----(可以序列化) .(同上)也可以在类的上面增加[Table(" ...
- 软件测试作业-selenium
一.作业要求 1.安装SeleniumIDE插件. 2.学会使用SeleniumIDE录制脚本和导出脚本. 3.访问网址使用学号登录系统,进入系统后可以看到该同学的git地址. 4.编写Seleniu ...
- input 框输入数字相关
input框限制只能输入正整数,逻辑与和或运算 有时需要限制文本框输入内容的类型,本节分享下正则表达式限制文本框只能输入数字.小数点.英文字母.汉字等代码. 例如,输入大于0的正整数 代码如下: &l ...
- RAP开发入门-运行第一个HelloWorld(二)
环境搭建好了之后我们就可以照惯例运行第一个helloworld程序了. (ps:这里钉几个资料吧 官网开发指导:http://help.eclipse.org/indigo/index.jsp?top ...
- NSPort与NSRunloop的关系是流与消息调度的关系
NSPort与NSRunloop的关系是流与消息调度的关系. NSPort 将流插入到消息调度队列: 相当于 Socket将流插入到应用一样 - (void)launchThread { NSPort ...
- python简单的购物系统
#coding = utf-8 #2016-11-19#我的工资是存在文件中的,执行后会判断是否存过工资,如果存过无需输入,直接购物,没存过需要输入工资#wages.txt是存工资的文件 import ...
- [修改高通平台WIFI MAC 地址] & [adb over wifi]
[修改高通平台WIFI MAC 地址]fccmd --helpfccmd startfccmd getwifimacfccmd setwifimac 74:AC:5F:F5:D7:40 [adb ov ...