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

Android Kotlin开发:如何实现全局可访问的AccessToken存储?

Android中全局管理Access Token的正确方案

一、自定义Application类(简单但需配合持久化)

你可以创建自定义Application子类存储token作为全局变量,但要注意进程重启后变量会丢失,所以必须配合持久化存储使用:

class MyApp : Application() {
    var accessToken: String? = null

    override fun onCreate() {
        super.onCreate()
        // 启动时从持久化存储恢复token
        accessToken = getSharedPreferences("app_prefs", MODE_PRIVATE)
            .getString("access_token", null)
    }

    // 保存token时同时持久化
    fun saveAccessToken(token: String) {
        accessToken = token
        getSharedPreferences("app_prefs", MODE_PRIVATE)
            .edit()
            .putString("access_token", token)
            .apply()
    }
}

在Activity中调用:

val token = (application as MyApp).accessToken

注意:记得在AndroidManifest.xml的<application>标签里指定android:name=".MyApp"。

二、封装持久化存储类(推荐,可靠)

直接将token存入SharedPreferences或Jetpack DataStore,封装成单例类供全局调用,这是最稳妥的方案——数据不会因进程重启丢失。

方案1:SharedPreferences单例封装

object TokenManager {
    private const val PREF_NAME = "token_prefs"
    private const val KEY_ACCESS_TOKEN = "access_token"

    fun saveAccessToken(context: Context, token: String) {
        context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
            .edit()
            .putString(KEY_ACCESS_TOKEN, token)
            .apply()
    }

    fun getAccessToken(context: Context): String? {
        return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
            .getString(KEY_ACCESS_TOKEN, null)
    }

    fun clearAccessToken(context: Context) {
        context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
            .edit()
            .remove(KEY_ACCESS_TOKEN)
            .apply()
    }
}

使用示例:

// 登录后保存token
TokenManager.saveAccessToken(this, "your_token_here")

// 其他Activity获取token
val token = TokenManager.getAccessToken(this)

方案2:Jetpack DataStore(现代方案,支持协程)

如果项目使用协程,推荐用DataStore替代SharedPreferences,它的线程安全性和可靠性更好:

class TokenManager(private val context: Context) {
    private val dataStore = context.createDataStore(name = "token_prefs")

    suspend fun saveAccessToken(token: String) {
        dataStore.edit { preferences ->
            preferences[PreferencesKeys.ACCESS_TOKEN] = token
        }
    }

    val accessTokenFlow: Flow<String?> = dataStore.data
        .map { preferences ->
            preferences[PreferencesKeys.ACCESS_TOKEN]
        }

    private object PreferencesKeys {
        val ACCESS_TOKEN = stringPreferencesKey("access_token")
    }
}

// 封装成单例避免重复创建
object TokenProvider {
    private var instance: TokenManager? = null

    fun getInstance(context: Context): TokenManager {
        return instance ?: synchronized(this) {
            val newInstance = TokenManager(context.applicationContext)
            instance = newInstance
            newInstance
        }
    }
}

使用示例(需在协程中调用):

// 保存token
lifecycleScope.launch {
    TokenProvider.getInstance(this@LoginActivity).saveAccessToken("your_token")
}

// 获取token并监听变化
lifecycleScope.launch {
    TokenProvider.getInstance(this@HomeActivity).accessTokenFlow.collect { token ->
        // 使用token调用API
    }
}

三、依赖注入(适合中大型项目)

如果是中大型项目,推荐用Hilt这类依赖注入框架,将TokenManager注入到需要的Activity、ViewModel或Repository中,避免到处传递Context:

  1. 配置Hilt后,创建TokenManager类:
class TokenManager @Inject constructor(
    @ApplicationContext private val context: Context
) {
    // 这里可复用上面的SharedPreferences或DataStore实现逻辑
}
  1. 在Activity中注入并使用:
@AndroidEntryPoint
class HomeActivity : AppCompatActivity() {
    @Inject lateinit var tokenManager: TokenManager

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val token = tokenManager.getAccessToken(context)
        // 使用token调用API
    }
}

不推荐直接用静态类/全局变量的原因

直接用静态变量存token虽然简单,但进程被系统回收后变量会清空,导致后续API调用失败;若处理不当还可能引发内存泄漏(比如持有Context引用)。所以一定要配合持久化存储,或直接采用持久化方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:20:48