You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin中使用Preferences DataStore保存登录会话与令牌?

在Kotlin中用Preferences DataStore实现登录会话持久化

1. 添加DataStore依赖

先在模块级build.gradle.kts中引入Preferences DataStore的依赖:

dependencies {
    implementation("androidx.datastore:datastore-preferences:1.0.0")
}

2. 创建SessionManager管理类

用单例模式封装DataStore的读写逻辑,避免重复创建实例:

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

// 扩展Context,初始化DataStore实例
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_session")

class SessionManager(private val context: Context) {
    // 定义存储用的Key
    companion object {
        private val USER_TOKEN = stringPreferencesKey("auth_token")
        private val USER_ID = stringPreferencesKey("user_id")
    }

    // 保存登录会话信息
    suspend fun saveSession(token: String, userId: String) {
        context.dataStore.edit { preferences ->
            preferences[USER_TOKEN] = token
            preferences[USER_ID] = userId
        }
    }

    // 读取令牌(以Flow形式返回,支持实时监听)
    val authToken: Flow<String?> = context.dataStore.data
        .map { preferences ->
            preferences[USER_TOKEN]
        }

    // 读取用户ID
    val userId: Flow<String?> = context.dataStore.data
        .map { preferences ->
            preferences[USER_ID]
        }

    // 清除会话数据(退出登录时调用)
    suspend fun clearSession() {
        context.dataStore.edit { preferences ->
            preferences.clear()
        }
    }
}

3. 登录成功后保存会话

当API登录请求返回成功(拿到令牌和用户ID),在协程中调用保存方法:

// 假设这是登录API的成功回调
fun handleLoginSuccess(token: String, userId: String) {
    CoroutineScope(Dispatchers.IO).launch {
        SessionManager(context).saveSession(token, userId)
    }
}

4. 应用启动时自动检查登录状态

在启动页(如SplashActivity)中读取会话状态,决定跳转页面:

class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash)

        lifecycleScope.launch {
            SessionManager(this@SplashActivity).authToken.collect { token ->
                val targetActivity = if (token.isNullOrEmpty()) {
                    LoginActivity::class.java
                } else {
                    MainActivity::class.java
                }
                startActivity(Intent(this@SplashActivity, targetActivity))
                finish()
            }
        }
    }
}

5. 退出登录时清除会话

在退出登录按钮的点击事件中,调用清除方法并跳转登录页:

btnLogout.setOnClickListener {
    lifecycleScope.launch(Dispatchers.IO) {
        SessionManager(this@MainActivity).clearSession()
        startActivity(Intent(this@MainActivity, LoginActivity::class.java))
        finish()
    }
}

额外提示

  • DataStore的所有读写操作必须在协程中执行,不能在主线程同步调用,避免ANR。
  • 如果需要存储复杂对象(如完整用户信息),可以改用Proto DataStore,但仅存令牌、ID这类简单数据时,Preferences DataStore足够高效。
  • 发起API请求时,可读取令牌添加到请求头:
lifecycleScope.launch {
    val token = SessionManager(context).authToken.first()
    val apiService = RetrofitClient.createService(token)
    // 调用API接口
}

内容的提问来源于stack exchange,提问作者Bryant Anthony

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 09:35:07