在没有上下文的情况下获取共享首选项

时间:2021-07-13 16:23:04

标签: android kotlin sharedpreferences android-context

大家晚上好!我想使用共享首选项来存储我的令牌(我知道这不安全,我是 android 开发新手,只是想尝试一下)然后将其传递给拦截器。如何在那里初始化共享首选项?谢谢!或者你能给我一个如何实现拦截器或存储令牌的提示。

抱歉,我已经尝试过搜索此主题,但无法实现其他开发人员的方法。

object NetworkModule {

    var sharedPreferences = //GET SHARED PREFERENCES THERE

    var authToken: String? = sharedPreferences.getString("Token", null)
    val baseURL = //my base url

    
    val loggingInterceptor = HttpLoggingInterceptor().apply {
        level = HttpLoggingInterceptor.Level.BODY
    }


    var httpClient = OkHttpClient.Builder().addInterceptor { chain ->
        chain.proceed(
            chain.request().newBuilder().also { it.addHeader("Authorization", "Bearer $authToken") }
                .build()
        )
    }.connectTimeout(10, TimeUnit.SECONDS)
        .writeTimeout(30, TimeUnit.SECONDS)
        .readTimeout(10, TimeUnit.SECONDS)
        .addNetworkInterceptor(loggingInterceptor)
        .build()

    val retrofit = Retrofit.Builder().baseUrl(baseURL).addConverterFactory(
        GsonConverterFactory.create()
    ).client(httpClient).build()


    val api: API by lazy { retrofit.create() }
    val apiClient = ApiClient(api)
}

1 个答案:

答案 0 :(得分:0)

您可以使用 SharedPreferences 从您的应用访问 ApplicationContext 任何地方。这是 Android 开发中非常常见的做法,而且非常安全。

要访问 ApplicationContext,请参阅以下代码:

  1. 在您的 Application 类中,添加一个 Application Singleton

    class MyApplication : Application() {
         override fun onCreate() {
            super.onCreate()
            instance = this
         }
    
         companion object {
             lateinit var instance: MyApplication
                 private set
         }
    }
    

    (What is an Application Class?)

  2. 在您的应用内的任何地方使用 ApplicationContext

    var sharedPreferences = getApplicationContext() //here you go!
    

此代码可以完成工作,但是,如果您对最佳 Android 开发实践感兴趣,请阅读:

推荐的 2 个选项

  1. 最佳实践:创建一个新的 Manager 类,负责应用的整个 SharedPreferences 使用(例如 SharedPreferenceManager)。此类是一个 Singleton 类,它使用 ApplicationContext 进行实例化,并且在 SharedPreferences 中具有与 CRUD 操作相关的所有方法,在您的情况下为 setTokengetToken。由于管理器类是独立的,因此不应导致任何 Lifecycle 错误或 NullPointer 错误。

    由于附加示例代码会使我的答案变得混乱,我决定引用 someone else's code here, this will teach you how to implement it.

  2. 如果您懒得遵循 #2:您可以使用已经为您完成此操作的库:Pixplicity/EasyPrefs

    • 易于使用,如 Manager 类 ✅
    • 不再有与 SharedPreferences ✅ 相关的错误
    • 您可以随时改装到任何现有项目中 ✅

如果您有任何问题,请告诉我。谢谢。