219 lines
4.0 KiB
Markdown
219 lines
4.0 KiB
Markdown
|
|
# MMKV
|
|||
|
|
|
|||
|
|
## 目录
|
|||
|
|
- [MMKV原理](#mmkv原理)
|
|||
|
|
- [MMKV优势](#mmkv优势)
|
|||
|
|
- [MMKV使用](#mmkv使用)
|
|||
|
|
- [MMKV性能](#mmkv性能)
|
|||
|
|
- [MMKV与SharedPreferences对比](#mmkv与sharedpreferences对比)
|
|||
|
|
- [MMKV最佳实践](#mmkv最佳实践)
|
|||
|
|
- [面试常见问题](#面试常见问题)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## MMKV原理
|
|||
|
|
|
|||
|
|
### MMKV 简介
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// MMKV:高性能键值存储框架
|
|||
|
|
// - 基于 mmap 内存映射
|
|||
|
|
// - 高性能、低延迟
|
|||
|
|
// - 支持多进程
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 存储原理
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// MMKV 使用 mmap 内存映射
|
|||
|
|
// 1. 将文件映射到内存
|
|||
|
|
// 2. 直接操作内存,自动同步到文件
|
|||
|
|
// 3. 避免系统调用,性能更好
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## MMKV优势
|
|||
|
|
|
|||
|
|
### 性能优势
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// MMKV 性能优势:
|
|||
|
|
// 1. 基于 mmap,性能更好
|
|||
|
|
// 2. 支持多进程,无需序列化
|
|||
|
|
// 3. 增量更新,只写入变更部分
|
|||
|
|
// 4. 无拷贝操作,直接操作内存
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 功能优势
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// MMKV 功能优势:
|
|||
|
|
// 1. 支持多进程
|
|||
|
|
// 2. 支持加密
|
|||
|
|
// 3. 支持自定义序列化
|
|||
|
|
// 4. API 简洁
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## MMKV使用
|
|||
|
|
|
|||
|
|
### 基本使用
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// 初始化
|
|||
|
|
MMKV.initialize(context);
|
|||
|
|
|
|||
|
|
// 获取默认实例
|
|||
|
|
MMKV kv = MMKV.defaultMMKV();
|
|||
|
|
|
|||
|
|
// 写入数据
|
|||
|
|
kv.encode("string", "value");
|
|||
|
|
kv.encode("int", 123);
|
|||
|
|
kv.encode("bool", true);
|
|||
|
|
kv.encode("float", 1.23f);
|
|||
|
|
|
|||
|
|
// 读取数据
|
|||
|
|
String str = kv.decodeString("string", "default");
|
|||
|
|
int i = kv.decodeInt("int", 0);
|
|||
|
|
boolean b = kv.decodeBool("bool", false);
|
|||
|
|
float f = kv.decodeFloat("float", 0.0f);
|
|||
|
|
|
|||
|
|
// 删除数据
|
|||
|
|
kv.removeValueForKey("string");
|
|||
|
|
kv.clearAll();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 多实例
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// 创建多实例
|
|||
|
|
MMKV kv1 = MMKV.mmkvWithID("id1");
|
|||
|
|
MMKV kv2 = MMKV.mmkvWithID("id2");
|
|||
|
|
|
|||
|
|
// 多进程实例
|
|||
|
|
MMKV kv = MMKV.mmkvWithID("multi_process", MMKV.MULTI_PROCESS_MODE);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 加密
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// 加密实例
|
|||
|
|
String cryptKey = "MyEncryptionKey";
|
|||
|
|
MMKV kv = MMKV.mmkvWithID("encrypted", MMKV.SINGLE_PROCESS_MODE, cryptKey);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## MMKV性能
|
|||
|
|
|
|||
|
|
### 性能对比
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// MMKV vs SharedPreferences
|
|||
|
|
// 写入性能:MMKV 快 100-300 倍
|
|||
|
|
// 读取性能:MMKV 快 10-50 倍
|
|||
|
|
// 多进程:MMKV 支持,SharedPreferences 不支持
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 性能测试
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// 写入测试
|
|||
|
|
long start = System.currentTimeMillis();
|
|||
|
|
for (int i = 0; i < 10000; i++) {
|
|||
|
|
mmkv.encode("key" + i, "value" + i);
|
|||
|
|
}
|
|||
|
|
long end = System.currentTimeMillis();
|
|||
|
|
Log.d("MMKV", "Write time: " + (end - start) + "ms");
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## MMKV与SharedPreferences对比
|
|||
|
|
|
|||
|
|
### 对比表
|
|||
|
|
|
|||
|
|
| 特性 | MMKV | SharedPreferences |
|
|||
|
|
|------|------|-------------------|
|
|||
|
|
| 性能 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
|
|||
|
|
| 多进程 | ✅ | ❌ |
|
|||
|
|
| 加密 | ✅ | ❌ |
|
|||
|
|
| 增量更新 | ✅ | ❌ |
|
|||
|
|
| 易用性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
|
|||
|
|
|
|||
|
|
### 迁移方案
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// 从 SharedPreferences 迁移到 MMKV
|
|||
|
|
SharedPreferences prefs = getSharedPreferences("prefs", Context.MODE_PRIVATE);
|
|||
|
|
MMKV mmkv = MMKV.defaultMMKV();
|
|||
|
|
|
|||
|
|
Map<String, ?> all = prefs.getAll();
|
|||
|
|
for (Map.Entry<String, ?> entry : all.entrySet()) {
|
|||
|
|
String key = entry.getKey();
|
|||
|
|
Object value = entry.getValue();
|
|||
|
|
if (value instanceof String) {
|
|||
|
|
mmkv.encode(key, (String) value);
|
|||
|
|
} else if (value instanceof Integer) {
|
|||
|
|
mmkv.encode(key, (Integer) value);
|
|||
|
|
}
|
|||
|
|
// ... 其他类型
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## MMKV最佳实践
|
|||
|
|
|
|||
|
|
### 1. 使用单例
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// 使用默认实例或单例
|
|||
|
|
MMKV kv = MMKV.defaultMMKV();
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 批量操作
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// MMKV 支持批量操作
|
|||
|
|
// 但通常不需要,因为性能已经很好
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 多进程使用
|
|||
|
|
|
|||
|
|
```java
|
|||
|
|
// 多进程场景使用 MULTI_PROCESS_MODE
|
|||
|
|
MMKV kv = MMKV.mmkvWithID("multi", MMKV.MULTI_PROCESS_MODE);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 面试常见问题
|
|||
|
|
|
|||
|
|
### Q1: MMKV 的原理?
|
|||
|
|
|
|||
|
|
**答案:**
|
|||
|
|
- 基于 mmap 内存映射
|
|||
|
|
- 将文件映射到内存,直接操作内存
|
|||
|
|
- 自动同步到文件,性能更好
|
|||
|
|
|
|||
|
|
### Q2: MMKV 的优势?
|
|||
|
|
|
|||
|
|
**答案:**
|
|||
|
|
1. 性能好:比 SharedPreferences 快很多
|
|||
|
|
2. 支持多进程
|
|||
|
|
3. 支持加密
|
|||
|
|
4. 增量更新
|
|||
|
|
|
|||
|
|
### Q3: MMKV 和 SharedPreferences 的区别?
|
|||
|
|
|
|||
|
|
**答案:**
|
|||
|
|
- **MMKV**:性能好,支持多进程,支持加密
|
|||
|
|
- **SharedPreferences**:性能一般,不支持多进程,不支持加密
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
*最后更新:2024年*
|