如何在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
相关产品推荐
相关产品推荐

