-
「Generated by Manus, instructions issued by binbinwang」
本章将深入探讨Android的数据存储与持久化技术,并与iOS的对应方案进行对比。作为一名iOS开发者,了解Android平台的数据存储机制将帮助你更好地设计跨平台应用的数据层。
6.1 SharedPreferences与轻量级存储
SharedPreferences基础
SharedPreferences是Android提供的一种轻量级键值对存储机制,适合存储简单的配置信息和应用设置。
基本用法:
1 | // 获取SharedPreferences实例 |
使用Jetpack Preferences库:
1 | // build.gradle |
与iOS UserDefaults对比
iOS的UserDefaults:
1 | // 获取UserDefaults实例 |
主要差异:
- Android的SharedPreferences需要通过edit()获取Editor对象,而iOS的UserDefaults直接设置值
- Android提供apply()(异步)和commit()(同步)两种提交方式,而iOS自动处理
- Android可以监听特定键的变化,而iOS只能监听整个UserDefaults的变化
- Android的SharedPreferences可以创建多个命名实例,而iOS通常使用单例standardUserDefaults
- Android需要显式提交更改,而iOS在iOS 12后不再需要显式调用synchronize()
6.2 文件存储
内部存储与外部存储
Android提供了内部存储和外部存储两种文件存储机制:
内部存储:
- 应用私有,其他应用无法访问
- 随应用卸载自动删除
- 不需要权限
外部存储:
- 可以是公共的,也可以是应用私有的
- 应用卸载时,私有外部存储会被删除,公共外部存储不会
- 访问公共外部存储需要权限
内部存储基本操作:
1 | // 写入文本文件 |
外部存储基本操作:
1 | // 检查外部存储状态 |
与iOS文件系统对比
iOS的文件系统:
1 | // 获取Documents目录 |
主要差异:
- Android区分内部存储和外部存储,而iOS主要使用沙盒目录(Documents、Library、tmp)
- Android的外部存储可以是公共的,而iOS应用只能访问自己的沙盒和特定共享区域
- Android 10+引入了分区存储,限制了对公共存储的直接访问,而iOS一直采用沙盒模型
- Android需要权限才能访问公共外部存储,而iOS通过文件选择器或照片库API访问用户文件
- Android应用卸载时会清理内部存储和私有外部存储,而iOS清理整个应用沙盒
6.3 SQLite数据库
SQLite基础操作
SQLite是Android内置的轻量级关系型数据库,适合存储结构化数据:
创建数据库帮助类:
1 | class DatabaseHelper(context: Context) : SQLiteOpenHelper( |
基本CRUD操作:
1 | class UserDao(private val dbHelper: DatabaseHelper) { |
Room持久化库
Room是Android Jetpack提供的SQLite抽象层,简化了数据库操作:
```
// 实体定义
@Entity(tableName = “users”)
data class User(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
@ColumnInfo(name = “name”) val name: String,
@ColumnInfo(name = “email”) val email: String,
@ColumnInfo(name = “age”) val age: Int,
@ColumnInfo(name = “created_at”) val createdAt: Long = System.currentTimeMillis()
)
// DAO接口
@Dao
interface UserDao {
@Insert
fun insert(user: User): Long
@Insert
fun insertAll(users: List<User>)
@Update
fun update(user: User): Int
@Delete
fun delete(user: User): Int
@Query("SELECT * FROM users")
fun getAllUsers(): List<User>
@Query("SELECT * FROM users WHERE id = :userId")
fun getUserById(userId: Long): User?
@Query("SELECT * FROM users WHERE age > :minAge ORDER BY age DESC")
fun getUsersOlderThan(minAge: Int): List<User>
// 返回LiveData(自动观察数据变化)
@Query("SELECT * FROM users ORDER BY name ASC")
fun observeAllUsers(): LiveData<List<User>>
// 使用Flow
@Query("SELECT * FROM users WHERE age > :minAge")
fun getUsersOlderThanFlow(minAge: Int): Flow<List<User>>
// 使用挂起函数
@Query("DELETE FROM users WHERE age < :maxAge")
suspend fun deleteYoungerThan(maxAge: Int): Int
}
// 数据库定义
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
companion object {
@Volatile
private var INSTANCE: AppDatabase? = null
fun getDatabase(context: Context): AppDatabase {
return INSTANCE ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
"app_database"
)
.fallbackToDestructiveMigration() // 升级失败时重建数据库
//.addMigrations(MIGRATION_1_2) // 添加迁移策略
.build()
INSTANCE = instance
instance
}
}
private val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE users ADD COLUMN phone_number TEXT")
}
}
}
}
// 使用Room
class Usegrep -n
in order to find the line numbers of what you are looking for.