第7章 数据存储全方案,详解持久化技术
在 Android 应用开发中,数据持久化是构建可靠、可恢复用户体验的基础能力。系统提供了多种存储方案,开发者需根据数据类型、访问频率、安全性和复杂度选择合适的方式。本文将深入讲解三种最常用的数据存储机制:

在 Android 应用开发中,数据持久化是构建可靠、可恢复用户体验的基础能力。系统提供了多种存储方案,开发者需根据数据类型、访问频率、安全性和复杂度选择合适的方式。本文将深入讲解三种最常用的数据存储机制:
- 文件存储(File Storage):适用于原始文本或二进制数据;
- SharedPreferences:适用于轻量级键值对配置;
- SQLite 数据库:适用于结构化、关系型数据管理。
📌 核心原则:
- 简单数据 → SharedPreferences;
- 原始流/大文件 → 内部/外部文件存储;
- 结构化数据 → SQLite / Room。
文件存储
文件存储是 Android 最基础的持久化方式,它将数据以原始字节流形式保存到设备文件系统中,不对内容做任何格式化处理。因此,它特别适合存储日志、缓存、图片、音频等二进制数据,或简单的文本记录。
存储位置分类
| 类型 | 路径 | 是否私有 | 是否需要权限 |
|---|---|---|---|
| 内部存储 | /data/data/<package>/files/ |
✅ 是 | ❌ 否 |
| 外部存储(私有) | /storage/emulated/0/Android/data/<package>/files/ |
✅ 是(应用卸载自动删除) | ❌ Android 10+ 不需要 |
| 外部存储(公共) | /storage/emulated/0/Pictures/ 等 |
❌ 否 | ✅ 需要 READ_EXTERNAL_STORAGE / WRITE_EXTERNAL_STORAGE |
🔒 安全建议:
敏感数据(如 token、用户信息)必须使用内部存储,避免被其他应用读取。
示例解析:内部文件读写
您提供的代码使用 openFileOutput() 和 openFileInput() 操作内部私有文件:
// 保存
val fos = openFileOutput("my_data.txt", MODE_PRIVATE)
fos.write(data.toByteArray())
fos.close()
// 读取
val fis = openFileInput("my_data.txt")
val content = fis.bufferedReader().use { it.readText() }
⚙️ 关键点:
MODE_PRIVATE:仅本应用可访问;- 文件名
"my_data.txt"无需带路径,系统自动存入内部目录;- 使用
BufferedReader提升大文件读取效率;- 务必关闭流(推荐使用
use {}自动管理资源)。
运行效果:
-
输入文本并点击“保存数据” → 数据写入内部文件;

-
点击“加载数据” → 从文件读取并显示;

🚫 局限性:
- 无法直接查询或更新部分内容;
- 大量结构化数据需自行设计解析格式(如 JSON、CSV);
- 不支持并发写入。
✅ 适用场景:
- 用户编辑的草稿;
- 网络请求缓存;
- 日志记录。
SharedPreferences 存储
SharedPreferences 是 Android 提供的轻量级键值对存储方案,底层基于 XML 文件实现,适合保存应用配置、用户偏好、登录状态等简单数据。
核心特性
- 数据类型支持:
String,Int,Long,Float,Boolean,Set<String>; - 线程安全:内部使用同步锁;
- 自动序列化:无需手动解析;
- 私有性:默认仅本应用可访问。
示例解析:保存用户信息
// 获取 SharedPreferences 实例
val sharedPrefs = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE)
// 保存
val editor = sharedPrefs.edit()
editor.putString("name", "张三")
editor.putInt("age", 25)
editor.putLong("timestamp", System.currentTimeMillis())
editor.apply() // 异步提交(推荐)
// 读取
val name = sharedPrefs.getString("name", "") ?: ""
val age = sharedPrefs.getInt("age", 0)
🔑
apply()vscommit():
apply():异步写入磁盘,不阻塞主线程(推荐);commit():同步写入,返回布尔值表示成功与否(慎用)。
布局与交互:
-
输入姓名和年龄 → 点击“保存数据”;

-
点击“加载数据” → 显示完整信息(含时间戳);

⚠️ 注意事项:
- 不要存储大量数据(如列表、对象),会导致 ANR;
- 避免频繁写入(如每秒多次),影响性能;
- 敏感信息需加密(如密码),可结合
EncryptedSharedPreferences(Jetpack Security 库)。
✅ 最佳实践:
// 封装工具类 object UserPrefs { private const val PREF_NAME = "user_prefs" fun saveUserInfo(context: Context, name: String, age: Int) { context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit { putString("name", name) putInt("age", age) } } }
数据库(SQLite)
当数据具有结构化、关联性、需频繁查询/更新时,SQLite 是 Android 官方推荐的嵌入式关系型数据库。
为什么选择 SQLite?
- 轻量高效:单文件数据库,无独立服务进程;
- ACID 支持:保证数据一致性;
- SQL 标准:支持复杂查询、索引、事务;
- Android 深度集成:通过
SQLiteOpenHelper管理。
📢 现代替代方案:
Google 推荐使用 Room Persistence Library(Jetpack 组件),它在 SQLite 上提供编译时 SQL 验证、LiveData 支持、Kotlin 协程等高级功能。但理解原生 SQLite 仍是基础。
示例解析:书籍管理系统
您的代码展示了完整的 CRUD 操作:
1. 数据模型
data class Book(
val id: Int = 0,
val name: String,
val author: String,
val price: Double,
val pages: Int
)
2. 数据库帮助类(MyDatabaseHelper)
继承 SQLiteOpenHelper,负责创建/升级表:
class MyDatabaseHelper(context: Context, name: String, version: Int)
: SQLiteOpenHelper(context, name, null, version) {
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE Book (id INTEGER PRIMARY KEY AUTOINCREMENT, ...)")
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("DROP TABLE IF EXISTS Book")
onCreate(db) // 简单粗暴,生产环境应做数据迁移
}
}
⚠️
onUpgrade警告:
直接DROP TABLE会丢失所有用户数据!正式项目应使用ALTER TABLE或版本迁移脚本。
3. CRUD 操作封装
- 增:
db.insert()→ 返回新记录 ID; - 删:
db.delete()→ 返回删除行数; - 改:
db.update()→ 返回更新行数; - 查:
db.query()→ 返回Cursor,需遍历解析。
fun addBook(book: Book): Long {
val db = writableDatabase
val values = ContentValues().apply {
put("name", book.name)
put("author", book.author)
// ...
}
return db.insert("Book", null, values).also { db.close() }
}
🔍
ContentValues优势:
- 类型安全(避免 SQL 注入);
- 自动转义特殊字符。
4. UI 交互
-
添加书籍:输入书名、作者、价格、页数 → 点击“添加”;

-
删除书籍:输入 ID → 弹出确认对话框 → 执行删除;

-
更新书籍:输入 ID 及新信息 → 更新对应记录;

-
查询所有:加载并格式化显示全部书籍;

✅ 高级查询示例(代码中已实现):
- 按作者模糊查询:
author LIKE '%关键词%'- 按价格范围筛选:
price <= ?
三种存储方式对比总结
| 特性 | 文件存储 | SharedPreferences | SQLite |
|---|---|---|---|
| 数据结构 | 无结构(原始字节) | 键值对 | 表格(结构化) |
| 查询能力 | 无(需全读解析) | 按 Key 获取 | 强大(SQL) |
| 性能 | 读写大文件快 | 小数据极快 | 中等(索引优化后快) |
| 安全性 | 内部存储高 | 默认高 | 默认高 |
| 适用数据量 | KB ~ MB | < 1MB | MB ~ GB |
| 典型场景 | 日志、缓存、媒体文件 | 设置、Token、状态标志 | 用户资料、订单、消息 |
最佳实践与避坑指南
🛡️ 安全性
- 敏感数据加密:使用
EncryptedSharedPreferences或Jetpack Security; - 避免外部存储明文:尤其 Android 10 以下需动态申请权限;
- SQL 注入防护:永远使用
?占位符 +selectionArgs,而非字符串拼接。
⚡ 性能优化
- SharedPreferences:避免在循环中频繁写入;
- SQLite:
- 批量操作使用事务:
db.beginTransaction(); - 为常查询字段添加索引:
CREATE INDEX idx_author ON Book(author);
- 批量操作使用事务:
- 文件:大文件使用
BufferedInputStream/OutputStream。
🧪 调试技巧
- 查看 SharedPreferences:
Device File Explorer→/data/data/<package>/shared_prefs/ - 查看数据库:使用 Database Inspector(Android Studio 内置工具);
- 日志输出:关键操作添加
Log.d()便于追踪。
🔄 现代化建议
- 优先使用 Jetpack 组件:
DataStore替代SharedPreferences(支持协程、类型安全);Room替代原生 SQLite(减少样板代码,提升可维护性)。
结语
掌握 文件、SharedPreferences、SQLite 三大存储方式,是 Android 开发者的必备技能。它们各有适用边界,合理选择能显著提升应用的性能、安全与用户体验。
💡 终极建议:
- 简单配置 →
DataStore;- 结构化数据 →
Room;- 原始文件 → 内部存储 + 加密。
通过本文的实战代码与深度解析,相信你已具备在真实项目中灵活运用数据持久化技术的能力。
更多推荐



所有评论(0)