存储方式 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
SQLite/Room | 结构化数据、频繁查询、需要事务支持 | 成熟稳定、支持复杂查询、数据持久化 | 单线程操作需异步处理、大容量数据性能下降 |
文件存储 | 非结构化数据、大体积二进制文件(如图片/视频缓存) | 简单易用、无需解析 | 文件管理复杂、搜索效率低 |
Realm/ObjectBox | 高性能对象存储、频繁读写操作 | 毫秒级延迟、自动索引、跨线程安全 | 学习成本较高、部分功能需付费 |
Protobuf+File | 二进制序列化、跨平台数据交换 | 体积小、解析快、版本兼容好 | 需手动管理序列化逻辑 |
Firebase Firestore | 云端同步、实时数据更新 | 自动同步、离线支持、规模可扩展 | 依赖网络、存在存储费用 |
// Room分页查询示例 @Query("SELECT FROM User ORDER BY id LIMIT :limit OFFSET :offset") List<User> getUsers(int limit, int offset);
// 配合LiveData实现懒加载
public LiveData<List
MutableLiveData<List
int offset = 0;
while (offset >= 0) {
List
if (users.isEmpty()) break;
data.postValue(users);
offset += pageSize;
}
return data;
}
2. 索引优化
```sql
-创建联合索引加速查询
CREATE INDEX idx_user_age_name ON User(age, name);
数据压缩
| 数据类型 | 压缩方案 |
|——————-|————————————————————————–|
| JSON文本 | GZIP压缩(可减少60%-80%体积) |
| Bitmap图像 | WebP格式(较PNG减少40%体积)或自动生成缩略图 |
| Protobuf数据 | 启用ZIP压缩选项(codec = COMPRESSED) |
批量操作
// Room批量插入示例 @Insert(onConflict = OnConflictStrategy.REPLACE) void insertUsers(List<User> users);
特性 | Realm | ObjectBox | SQLite(Room) |
---|---|---|---|
对象映射 | 自动双向映射 | 编译时生成映射 | 需手动转换 |
多线程支持 | 跨线程共享实例 | 独立实例 | 需线程切换 |
查询性能 | 中等(约5000条/ms) | 高(约10000条/ms) | 低(约2000条/ms) |
内存占用 | 较高(需注意大数据集) | 较低(按需加载) | 适中 |
学习成本 | 中等(类似SQL) | 较高(DSL语法) | 低(标准SQL) |
大数据冷存储
// 使用Protobuf存储历史日志 byte[] data = logBook.build().toByteArray(); FileOutputStream output = openFileOutput("log_2023.data", MODE_APPEND); output.write(data);
跨进程共享
<!-AndroidManifest声明ContentProvider --> <provider android:name=".data.UserProvider" android:exported="false"/>
// AIDL接口定义 interface IUserService { List<User> getAllUsers(); }
Q1:Room数据库在存储10万条记录时出现ANR怎么办?
A1:建议采取以下措施:
RxJava
或Coroutine
进行异步操作@Index
注解为高频查询字段建立索引Paging3
库)Q2:如何选择Gson和Protobuf进行对象序列化?
A1:对比参考:
| 维度 | Gson | Protobuf |
|———————|——————————-|——————————-|
| 性能 | 中等(约200kb/ms) | 高(约50kb/ms) |
| 向前兼容 | 较差(需保持相同版本) | 优秀(支持字段增减) |
| 二进制支持 | 仅JSON文本 | 原生支持二进制格式 |
| 学习成本 | 低(注解驱动) | 中(需.proto文件定义) |
| 适用场景 | 简单配置数据 | 高频传输/存储大量数据