Android应用无法获取并写入Token问题求助
核心问题分析
- 数据模型字段不匹配:OkHttp返回的响应字段是
auth_token,但你的UserToken数据类定义的是userToken,默认JSON解析器(如Gson/Moshi)无法自动映射这两个字段,导致解析后UserToken实例为null,最终ViewModel的userTokenLiveData的data字段为空。 - 错误的异步结果处理方式:你用
Thread.sleep()阻塞主线程等待异步请求结果,且仅在初始化时获取一次token变量的值——LiveData的value不会自动同步到该变量,即使后续请求完成,token仍保持初始的null值。
修复步骤
1. 修正数据模型的字段映射
给UserToken的字段添加序列化注解,匹配接口返回的字段名:
// Gson使用SerializedName import com.google.gson.annotations.SerializedName data class UserToken( @SerializedName("auth_token") val userToken: String ) // 若使用Moshi则替换为Json注解 // import com.squareup.moshi.Json // data class UserToken( // @Json(name = "auth_token") // val userToken: String // )
2. 正确监听LiveData结果,移除Thread.sleep()
放弃阻塞线程的方式,通过LiveData观察者在请求完成后处理Token存储和页面跳转:
// 替换原有的Token写入代码 authenticationUserViewModel.authUser(AuthUser("Serg!@#$", "Serg")) authenticationUserViewModel.userToken.observe(viewLifecycleOwner) { resource -> when(resource) { is Resource.Success -> { resource.data?.let { userToken -> saveUserToken(userToken.userToken) } ?: run { saveUserToken("пусто") } navController.navigate(Graph.HOME) } is Resource.Error -> { // 可添加错误提示逻辑,比如Toast提示登录失败 saveUserToken("пусто") navController.navigate(Graph.HOME) } is Resource.Loading -> { // 显示加载状态,比如展示ProgressBar } } }
3. 确认SharedPreferences初始化时机
确保prefUserToken在调用saveUserToken前完成初始化,比如在Activity的onCreate中执行:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ...其他初始化逻辑 prefUserToken = getSharedPreferences("UserToken", Context.MODE_PRIVATE) }
额外建议
- 禁止在主线程调用
Thread.sleep(),会引发UI卡顿甚至ANR - 统一处理Resource的Loading、Success、Error状态,给用户明确的交互反馈
- 可将
prefUserToken改为非空类型(确保初始化后再使用),或在saveUserToken中添加空指针检查
内容的提问来源于stack exchange,提问作者Kring Lord
相关产品推荐
相关产品推荐

