没有合适的资源?快使用搜索试试~ 我知道了~
首页Android 源码解析及微信 MMKV 源码深入分析
Android 源码解析及微信 MMKV 源码深入分析
需积分: 2 1 下载量 119 浏览量
更新于2023-11-24
收藏 4.97MB PDF 举报
Android 源码解析是指对Android操作系统的源代码进行深入的分析和解读的过程。通过对Android源码的解析,可以更加全面地了解Android系统的内部结构和运行机制,为Android应用程序的开发和调试提供参考和指导。 本文主要介绍了Android开发相关的源码精编解析和微信MMKV源码的深入解析。 在Android开发相关的源码精编解析的部分,主要涉及以下几个方面: 首先是初始化部分,作者介绍了Android应用程序的初始化过程,包括创建Application对象、加载资源、注册组件等。通过对源码的解析,读者可以了解到Android应用程序的初始化流程和相关的类和接口。 其次是获取部分,作者详细讲解了在Android应用程序中获取各种系统服务的方法和原理。通过对源码的解析,读者可以了解到不同系统服务的实现原理以及如何在应用程序中进行调用和使用。 然后是获取MMKV对象的部分,作者对微信MMKV库进行了源码解析。MMKV是一个高性能、高稳定性的键值存储引擎,可以替代SharedPreferences用于存储小量数据。通过对源码的解析,读者可以了解到MMKV的内部实现原理以及如何在应用程序中使用MMKV。 最后是从文件加载数据的部分,作者介绍了从文件加载数据的方法和原理。通过对源码的解析,读者可以了解到Android系统是如何从文件中读取数据并进行相关的处理的。 总的来说,通过对Android源码的解析,可以更加深入地了解Android系统的内部运行机制和开发相关的知识。这对于Android开发人员来说是非常有价值的,可以帮助他们更高效地进行应用程序的开发和调试工作。
资源详情
资源推荐
![](https://csdnimg.cn/release/download_crawler_static/87889927/bg10.jpg)
string key = jstring2string(env, oKey);
return (jboolean) kv->setInt32(value, key);
}
return (jboolean) false;
}
这里将 Java 层持有的 NativeHandle 转为了对应的 MMKV 对象,之后调用了
其 setInt32 方法:
bool MMKV::setInt32(int32_t value, const std::string &key) {
if (key.empty()) {
return false;
}
//
构造值对应的
MMBuffer
,通过
CodedOutputData
将其写入
Buffer
size_t size = pbInt32Size(value);
MMBuffer data(size);
CodedOutputData output(data.getPtr(), size);
output.writeInt32(value);
return setDataForKey(std::move(data), key);
}
这里首先获取到了写入的 value 在 protobuf 中所占据的大小,之后为其构造
了对应的 MMBuffer 并将数据写入了这段 Buffer,最后调用到
了 setDataForKey 方法(std::move 是 C++ 11 的特性,我们可以简单理解成赋
值,它通过直接移动内存减少了拷贝)。
同时可以发现 CodedOutputData 是与 Buffer 交互的桥梁,可以通过它实现
向 MMBuffer 中写入数据。
bool MMKV::setDataForKey(MMBuffer &&data, const std::string &key) {
if (data.length() == 0 || key.empty()) {
return false;
}
//
获取写锁
SCOPEDLOCK(m_lock);
SCOPEDLOCK(m_exclusiveProcessLock);
//
确保数据已读入内存
checkLoadData();
![](https://csdnimg.cn/release/download_crawler_static/87889927/bg11.jpg)
//
将
data
写入
map
中
auto itr = m_dic.find(key);
if (itr == m_dic.end()) {
itr = m_dic.emplace(key, std::move(data)).first;
} else {
itr->second = std::move(data);
}
m_hasFullWriteback = false;
return appendDataWithKey(itr->second, key);
}
这里在确保数据已读入内存的情况下将 data 写入了对应的 map,之后调用
了 appendDataWithKey 方法:
bool MMKV::appendDataWithKey(const MMBuffer &data, const std::string &key) {
size_t keyLength = key.length();
//
计算写入到映射空间中的
size
size_t size = keyLength + pbRawVarint32Size((int32_t) keyLength);
size += data.length() + pbRawVarint32Size((int32_t) data.length());
//
要写入,获取写锁
SCOPEDLOCK(m_exclusiveProcessLock);
//
确定剩余映射空间足够
bool hasEnoughSize = ensureMemorySize(size);
if (!hasEnoughSize || !isFileValid()) {
return false;
}
if (m_actualSize == 0) {
auto allData = MiniPBCoder::encodeDataWithObject(m_dic);
if (allData.length() > 0) {
if (m_crypter) {
m_crypter->reset();
auto ptr = (unsigned char *) allData.getPtr();
m_crypter->encrypt(ptr, ptr, allData.length());
}
writeAcutalSize(allData.length());
m_output->writeRawData(allData); // note: don't write size of data
recaculateCRCDigest();
return true;
}
return false;
} else {
writeAcutalSize(m_actualSize + size);
m_output->writeString(key);
![](https://csdnimg.cn/release/download_crawler_static/87889927/bg12.jpg)
m_output->writeData(data); // note: write size of data
auto ptr = (uint8_t *) m_ptr + Fixed32Size + m_actualSize - size;
if (m_crypter) {
m_crypter->encrypt(ptr, ptr, size)
}
updateCRCDigest(ptr, size, KeepSequence);
return true;
}
}
这里首先计算了即将写入到映射空间的内容大小,之后调用
了 ensureMemorySize 方法确保剩余映射空间足够。
如果 m_actualSize 为 0,则会通过 MiniPBCoder::encodeDataWithObject 将整个
map 转换为对应的 MMBuffer,加密后通过 CodedOutputData 写入,最后重新计
算 CRC 校验码。否则会将 key 和对应 data 写入,最后更新 CRC 校验码。
m_actualSize 是位于文件的首部的,因此是否为 0 取决于文件对应位置。
同时值得注意的是:由于 protobuf 不支持增量更新,为了避免全量写入带来的
性能问题,MMKV 在文件中的写入并不是通过修改文件对应的位置,而是直接
在后面 append 一条新的数据,即使是修改了已存在的 key。而读取时只记录
最后一条对应 key 的数据,这样显然会在文件中存在冗余的数据。这样设计的
原因我认为是出于性能的考量,MMKV 中存在着一套内存重整机制用于对冗余
的 key-value 数据进行处理。它正是在确保内存充足时实现的。
内存重整
我们接下来看看 ensureMemorySize 是如何确保映射空间是否足够的:
![](https://csdnimg.cn/release/download_crawler_static/87889927/bg13.jpg)
bool MMKV::ensureMemorySize(size_t newSize) {
// ...
if (newSize >= m_output->spaceLeft()) {
//
如果内存剩余大小不足以写入,尝试进行内存重整,将
map
中的数据重新写入
prot
obuf
文件
static const int offset = pbFixed32Size(0);
MMBuffer data = MiniPBCoder::encodeDataWithObject(m_dic);
size_t lenNeeded = data.length() + offset + newSize;
if (m_isAshmem) {
if (lenNeeded > m_size) {
MMKVWarning("ashmem %s reach size limit:%zu, consider configure
with larger size",
m_mmapID.c_str(), m_size);
return false;
}
} else {
size_t avgItemSize = lenNeeded / std::max<size_t>(1, m_dic.size());
size_t futureUsage = avgItemSize * std::max<size_t>(8, (m_dic.size()
+ 1) / 2);
//
如果内存重整后仍不足以写入,则将大小不断乘
2
直至足够写入,最后通过
mma
p
重新映射文件
if (lenNeeded >= m_size || (lenNeeded + futureUsage) >= m_size) {
size_t oldSize = m_size;
do {
// double
空间直至足够
m_size *= 2;
} while (lenNeeded + futureUsage >= m_size);
// ...
if (ftruncate(m_fd, m_size) != 0) {
MMKVError("fail to truncate [%s] to size %zu, %s", m_mmapID.
c_str(), m_size,
strerror(errno));
m_size = oldSize;
return false;
}
//
用零填充不足部分
if (!zeroFillFile(m_fd, oldSize, m_size - oldSize)) {
MMKVError("fail to zeroFile [%s] to size %zu, %s", m_mmapID.
c_str(), m_size,
strerror(errno));
m_size = oldSize;
return false;
}
// unmap
![](https://csdnimg.cn/release/download_crawler_static/87889927/bg14.jpg)
if (munmap(m_ptr, oldSize) != 0) {
MMKVError("fail to munmap [%s], %s", m_mmapID.c_str(), strer
ror(errno));
}
//
重新通过
mmap
映射
m_ptr = (char *) mmap(m_ptr, m_size, PROT_READ | PROT_WRITE, MAP
_SHARED, m_fd, 0);
if (m_ptr == MAP_FAILED) {
MMKVError("fail to mmap [%s], %s", m_mmapID.c_str(), strerro
r(errno));
}
// check if we fail to make more space
if (!isFileValid()) {
MMKVWarning("[%s] file not valid", m_mmapID.c_str());
return false;
}
}
}
//
加密数据
if (m_crypter) {
m_crypter->reset();
auto ptr = (unsigned char *) data.getPtr();
m_crypter->encrypt(ptr, ptr, data.length());
}
//
重新构建并写入数据
writeAcutalSize(data.length());
delete m_output;
m_output = new CodedOutputData(m_ptr + offset, m_size - offset);
m_output->writeRawData(data);
recaculateCRCDigest();
m_hasFullWriteback = true;
}
return true;
}
这里代码看起来也比较长,它对 MMKV 的内存重整进行了实现,步骤如下:
1. 当剩余映射空间不足以写入需要写入的内容,尝试进行内存重整
2. 内存重整会将文件清空,将 map 中的数据重新写入文件,从而去除冗余
数据
剩余486页未读,继续阅读
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://profile-avatar.csdnimg.cn/be2da0f811c94967bba160225121757d_junlin0228.jpg!1)
圆如意
- 粉丝: 0
- 资源: 7
上传资源 快速赚钱
我的内容管理 收起
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助
![](https://csdnimg.cn/release/wenkucmsfe/public/img/voice.245cc511.png)
会员权益专享
最新资源
- VMP技术解析:Handle块优化与壳模板初始化
- C++ Primer 第四版更新:现代编程风格与标准库
- 计算机系统基础实验:缓冲区溢出攻击(Lab3)
- 中国结算网上业务平台:证券登记操作详解与常见问题
- FPGA驱动的五子棋博弈系统:加速与创新娱乐体验
- 多旋翼飞行器定点位置控制器设计实验
- 基于流量预测与潮汐效应的动态载频优化策略
- SQL练习:查询分析与高级操作
- 海底数据中心散热优化:从MATLAB到动态模拟
- 移动应用作业:MyDiaryBook - Google Material Design 日记APP
- Linux提权技术详解:从内核漏洞到Sudo配置错误
- 93分钟快速入门 LaTeX:从入门到实践
- 5G测试新挑战与罗德与施瓦茨解决方案
- EAS系统性能优化与故障诊断指南
- Java并发编程:JUC核心概念解析与应用
- 数据结构实验报告:基于不同存储结构的线性表和树实现
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
![](https://img-home.csdnimg.cn/images/20220527035711.png)
![](https://img-home.csdnimg.cn/images/20220527035711.png)
![](https://img-home.csdnimg.cn/images/20220527035111.png)
安全验证
文档复制为VIP权益,开通VIP直接复制
![](https://csdnimg.cn/release/wenkucmsfe/public/img/green-success.6a4acb44.png)