一、核心持久化方案
1. SharedPreferences
- 用途:存储简单的键值对(如用户设置、标记位)。
- 特点:轻量级、XML 格式存储,适合小数据量。
- 代码示例:kotlin
// 获取 SharedPreferences 实例 val sharedPref = context.getSharedPreferences("MyPrefs", Context.MODE_PRIVATE) // 写入数据 sharedPref.edit().apply { putString("username", "Alice") putInt("score", 100) apply() // 异步提交(推荐) // commit() 同步提交(可能阻塞主线程) } // 读取数据 val username = sharedPref.getString("username", "default") val score = sharedPref.getInt("score", 0)
2. 文件存储
- 用途:存储文本、二进制文件(如图片、缓存)。
- 分类:
- 内部存储:私有目录(
/data/data/<包名>/files
),无需权限。 - 外部存储:公共目录(如 Downloads),需
WRITE_EXTERNAL_STORAGE
权限(Android 10+ 需分区存储适配)。
- 内部存储:私有目录(
示例代码:
kotlin
// 写入内部文件
val fileContent = "Hello, World!"
context.openFileOutput("my_file.txt", Context.MODE_PRIVATE).use {
it.write(fileContent.toByteArray())
}
// 读取内部文件
context.openFileInput("my_file.txt").use {
val content = it.bufferedReader().readText()
}
// 写入外部公共目录(需权限)
val imageFile = File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "my_image.jpg")
imageFile.outputStream().use {
it.write(bitmapBytes)
}
3. SQLite 数据库
- 用途:存储结构化数据(如用户信息、交易记录)。
- 原生 API:
SQLiteOpenHelper
,需手动处理 SQL。 - 代码示例:kotlin
class MyDbHelper(context: Context) : SQLiteOpenHelper(context, "my_db", null, 1) { override fun onCreate(db: SQLiteDatabase) { db.execSQL("CREATE TABLE User (id INTEGER PRIMARY KEY, name TEXT)") } override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {} } // 插入数据 val db = MyDbHelper(context).writableDatabase db.execSQL("INSERT INTO User (name) VALUES (?)", arrayOf("Alice")) // 查询数据 val cursor = db.rawQuery("SELECT * FROM User", null) while (cursor.moveToNext()) { val name = cursor.getString(cursor.getColumnIndex("name")) } cursor.close()
4. Room Persistence Library
- 用途:SQLite 的抽象层,提供编译时 SQL 校验、简化数据库操作。
- 核心组件:
@Entity
:定义数据表结构。@Dao
:数据库操作接口。@Database
:数据库持有类。
完整示例:
kotlin
// 定义 Entity
@Entity
data class User(
@PrimaryKey val id: Int,
val name: String,
val age: Int
)
// 定义 Dao
@Dao
interface UserDao {
@Query("SELECT * FROM User")
fun getAll(): List<User>
@Insert
fun insert(user: User)
@Delete
fun delete(user: User)
}
// 定义 Database
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
// 初始化数据库
val db = Room.databaseBuilder(
context,
AppDatabase::class.java, "my-database"
).build()
// 使用协程异步操作
lifecycleScope.launch {
val users = withContext(Dispatchers.IO) {
db.userDao().getAll()
}
}
5. DataStore
- 用途:替代 SharedPreferences,支持异步操作、类型安全。
- 两种实现:
- Preferences DataStore:键值对存储。
- Proto DataStore:使用 Protobuf 存储结构化数据。
示例代码(Preferences DataStore):
kotlin
// 定义键
val USER_NAME_KEY = preferencesKey<String>("user_name")
// 创建 DataStore
val dataStore = context.createDataStore("settings")
// 写入数据
dataStore.edit { preferences ->
preferences[USER_NAME_KEY] = "Bob"
}
// 读取数据(返回 Flow)
val userNameFlow: Flow<String> = dataStore.data
.map { preferences ->
preferences[USER_NAME_KEY] ?: "default"
}
二、方案对比与选型
技术 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
SharedPreferences | 简单配置项(如开关、用户名) | 使用简单,轻量级 | 不适合复杂数据,无类型安全 |
文件存储 | 大文件(图片、日志)、非结构化数据 | 灵活,支持任意格式 | 需手动管理读写,无结构化查询 |
SQLite | 复杂结构化数据 | 支持 SQL 查询,成熟稳定 | 需编写 SQL,维护成本高 |
Room | 复杂结构化数据 | 编译时校验,与 LiveData/Flow 集成 | 需定义 Entity/Dao,学习曲线略高 |
DataStore | 替代 SharedPreferences | 异步安全,支持协程 | 迁移成本(旧项目需替换 SharedPref) |
三、高级技巧与注意事项
1. 数据库迁移(Room)
- 版本升级时修改表结构:kotlin
Room.databaseBuilder(...) .addMigrations(object : Migration(1, 2) { override fun migrate(database: SupportSQLiteDatabase) { database.execSQL("ALTER TABLE User ADD COLUMN email TEXT") } }) .build()
2. 加密存储
- 敏感数据(如令牌、密码):
- 使用
EncryptedSharedPreferences
(Android 6.0+):kotlinval masterKey = MasterKey.Builder(context) .setKeyScheme(MasterKey.KeyScheme.AES256_GCM) .build() val sharedPref = EncryptedSharedPreferences.create( context, "secret_prefs", masterKey, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM )
- 数据库加密:使用 SQLCipher 或 Room 加密扩展库。
- 使用
3. 文件存储最佳实践
- 缓存文件:使用
context.cacheDir
,系统可能自动清理。 - 分区存储(Android 10+):
- 访问公共目录需
READ_EXTERNAL_STORAGE
权限。 - 使用
MediaStore
或Storage Access Framework
。
- 访问公共目录需
4. 数据备份
- Auto Backup:配置
AndroidManifest.xml
自动备份到 Google Drive。xml<application android:allowBackup="true" android:fullBackupContent="@xml/backup_rules">
- 排除特定文件:创建
res/xml/backup_rules.xml
。
- 排除特定文件:创建
四、完整示例:Room + ViewModel + LiveData
kotlin
// ViewModel
class UserViewModel(application: Application) : AndroidViewModel(application) {
private val db = Room.databaseBuilder(
application,
AppDatabase::class.java, "user-db"
).build()
private val _users = MutableLiveData<List<User>>()
val users: LiveData<List<User>> = _users
fun loadUsers() {
viewModelScope.launch {
_users.value = withContext(Dispatchers.IO) {
db.userDao().getAll()
}
}
}
fun addUser(name: String, age: Int) {
viewModelScope.launch {
withContext(Dispatchers.IO) {
db.userDao().insert(User(0, name, age))
}
loadUsers()
}
}
}
// Activity/Fragment 中观察数据
userViewModel.users.observe(this) { users ->
// 更新 UI
}
五、总结建议
- 简单配置:优先使用 DataStore 或 SharedPreferences。
- 结构化数据:选择 Room + SQLite,利用类型安全和 LiveData/Flow 响应式支持。
- 大文件/媒体:使用文件存储,注意分区存储限制。
- 安全敏感数据:务必加密(如 EncryptedSharedPreferences 或 SQLCipher)。
- 版本兼容:处理数据库迁移和旧设备适配。
通过合理选择持久化方案,可显著提升应用性能和可维护性。