存储与网络

132 阅读2分钟

第六章:存储与网络

SharedPreferences(对比 LocalStorage)

SharedPreferences 是 Android 中最简单的数据持久化方案,与 Web 中的 LocalStorage 非常相似:

// 存储数据
val prefs = getSharedPreferences("app_settings", Context.MODE_PRIVATE)
prefs.edit().apply {
    putString("user_name", "张三")
    putBoolean("is_logged_in", true)
    putInt("theme_mode", 1)
    apply()
}

// 读取数据
val userName = prefs.getString("user_name", "") // 第二个参数为默认值
val isLoggedIn = prefs.getBoolean("is_logged_in", false)

Room 数据库

Room 是 Android 官方推荐的 SQLite 数据库封装,使用方式类似于前端的 ORM 框架:

定义实体

@Entity(tableName = "users")
data class User(
    @PrimaryKey val uid: Int,
    @ColumnInfo(name = "first_name") val firstName: String,
    @ColumnInfo(name = "last_name") val lastName: String,
    val age: Int
)

定义 DAO(Data Access Object)

@Dao
interface UserDao {
    @Query("SELECT * FROM users")
    fun getAll(): List<User>

    @Query("SELECT * FROM users WHERE uid = :userId")
    fun getById(userId: Int): User

    @Insert
    fun insertUser(user: User)

    @Delete
    fun deleteUser(user: User)
}

创建数据库

@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

// 初始化数据库
val db = Room.databaseBuilder(
    applicationContext,
    AppDatabase::class.java, 
    "database-name"
).build()

// 使用数据库
lifecycleScope.launch(Dispatchers.IO) {
    val userDao = db.userDao()
    userDao.insertUser(User(1, "张", "三", 25))
    val users = userDao.getAll()
}

Retrofit 网络请求

Retrofit 是目前最流行的 Android 网络请求库,用法类似于 Axios:

定义 API 接口

interface ApiService {
    @GET("users/{id}")
    suspend fun getUser(@Path("id") userId: Int): User

    @POST("users")
    suspend fun createUser(@Body user: User): Response<User>
}

配置 Retrofit

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

val apiService = retrofit.create(ApiService::class.java)

发起请求

class UserRepository {
    suspend fun getUser(id: Int): Result<User> = try {
        val response = apiService.getUser(id)
        Result.success(response)
    } catch (e: Exception) {
        Result.failure(e)
    }
}

// 在 ViewModel 中使用
class UserViewModel : ViewModel() {
    private val repository = UserRepository()
    
    fun fetchUser(id: Int) {
        viewModelScope.launch {
            when (val result = repository.getUser(id)) {
                is Result.Success -> {
                    // 处理成功响应
                }
                is Result.Error -> {
                    // 处理错误
                }
            }
        }
    }
}

文件系统操作

Android 提供了多种文件存储方式:

内部存储

// 写入文件
val fileName = "my_file.txt"
val fileContent = "Hello, Android!"
context.openFileOutput(fileName, Context.MODE_PRIVATE).use { 
    it.write(fileContent.toByteArray())
}

// 读取文件
val content = context.openFileInput(fileName).bufferedReader().use {
    it.readText()
}

外部存储

// 检查权限
if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
    val file = File(
        Environment.getExternalStorageDirectory(),
        "MyFolder/myfile.txt"
    )
    
    // 写入文件
    file.writeText("Hello, External Storage!")
    
    // 读取文件
    val content = file.readText()
}

缓存文件

// 获取缓存目录
val cacheFile = File(context.cacheDir, "temp_file")

// 写入缓存
cacheFile.writeText("Temporary data")

// 清理缓存
cacheFile.delete()

媒体文件

对于图片、音频、视频等媒体文件,应该使用 MediaStore API:

// 保存图片到相册
val values = ContentValues().apply {
    put(MediaStore.Images.Media.DISPLAY_NAME, "image.jpg")
    put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
}

val uri = contentResolver.insert(
    MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
    values
)

uri?.let {
    contentResolver.openOutputStream(it).use { outputStream ->
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
    }
}

Android 的存储系统比 Web 更复杂,但也提供了更多的灵活性和安全性。下一章我们将探讨现代 Android 开发中的一些重要概念和工具。