首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android 全局數據存儲方案:Application 類、SharedPreferences、DataStore、Room 選型指南

     編輯:程式設計疑難解答

場景

用戶登錄後,用戶名、頭像、Token 等信息需在多 Activity/Fragment/Service 中頻繁讀寫。

方案對比

方案優勢劣勢適用場景
自定義 Application 類持有靜態/實例字段極快、無序列化開銷、支持任意對象進程被殺後數據丟失、內存洩漏風險、不支持跨進程臨時緩存、非持久化需求
SharedPreferences (XML)輕量、進程安全、自動持久化同步寫入阻塞主線程、不支持複雜對象、apply() 異步無回調少量鍵值對、用戶偏好設定
Jetpack DataStore (Preferences/Proto)基於協程/Flow、主線程安全、支持遷移、類型安全需學習 Flow、Proto 需定義 schema現代應用首選、替代 SP
Room DatabaseSQL 能力、觀察者模式 (LiveData/Flow)、編譯期驗證、支持複雜查詢樣板代碼多、遷移麻煩、體積較大結構化數據、列表、關聯查詢
MMKV (騰訊開源)極高性能 (mmap)、支持多進程、加密、自動異步刷盤第三方依賴、非 Google 官方高頻讀寫、大對象、替代 SP/DataStore

推薦架構:Repository + DataStore + 內存緩存

// UserRepository.kt
class UserRepository @Inject constructor(
    private val dataStore: DataStore,
    private val api: UserApi
) {
    private val _user = MutableStateFlow(null)
    val user: StateFlow = _user

    suspend fun load() {
        val prefs = dataStore.data.first()  // 或 collectAsStateFlow()
        val token = prefs[TOKEN_KEY] ?: ""
        if (token.isNotBlank()) {
            _user.value = User(token, prefs[NAME_KEY]!!, prefs[AVATAR_KEY]!!)
        }
    }

    suspend fun login(account: String, pwd: String) {
        val resp = api.login(account, pwd)
        dataStore.edit { it[TOKEN_KEY] = resp.token; it[NAME_KEY] = resp.name; it[AVATAR_KEY] = resp.avatar }
        _user.value = User(resp.token, resp.name, resp.avatar)
    }

    fun getUserSync() = _user.value  // 同步快速讀取
}

使用姿勢

  • Activity/Fragment:viewModel.user.observe(this) { updateUI(it) };
  • 非 UI 線程/Service:repository.getUserSync() 或 withContext(Dispatchers.IO) { dataStore.data.first() };
  • 跨進程:DataStore 基於 SharedPreferences 實現,天然進程安全;MMKV 亦支持。

避坑指南

  • 不要在 Application 靜態字段存放大對象 (Bitmap、Context) → 內存洩漏;
  • SharedPreferences edit().commit() 嚴禁主線程調用,務必用 apply() 或遷移 DataStore;
  • Token 過期自動刷新邏輯集中在 Repository,避免分散在各調用處。

總結

現代 Android 開發首選 DataStore + Repository 模式,兼顧性能、類型安全、主線程友好與生命周期感知。舊項目可漸進式遷移,新項目直接上 DataStore/Room/MMKV。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved