【问题标题】:Get shared preferences without context在没有上下文的情况下获取共享首选项
【发布时间】:2021-07-13 16:23:04
【问题描述】:

大家晚上好!我想使用共享首选项来存储我的令牌(我知道这不安全,我是 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)
}

【问题讨论】:

    标签: android kotlin sharedpreferences android-context


    【解决方案1】:

    您可以使用ApplicationContext 从您的应用程序中任何地方访问SharedPreferences。这是 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 Class ✅
      • 没有更多与SharedPreferences 相关的错误✅
      • 您可以随时改装到任何现有项目中 ✅

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

    【讨论】:

    • 此代码不适用于单例。您永远不会将变量设置为任何值。并且没有理由使公共属性可以为空,因为在创建应用程序后它永远不会为空。而且它不在伴生对象中。这是一个正确的方法:stackoverflow.com/a/37412029/506796
    • @Tenfour04 是的,忘了让它成为伴生对象!修好了。
    • @minchaej,谢谢!我认为这是我正在寻找的,但我没有正确理解。我使用您提供的库执行了以下步骤: 1. 使用给定代码创建类 PrefsApplication(只是在随机位置) 2. 尝试在 logcat 中使用 Prefs.putString("Token","myAuthToken") :原因:java .lang.RuntimeException:Prefs 类未正确实例化。请在 Application 类 onCreate 中调用 Builder.setContext().build()。我认为我在 PrefsApplication 类上犯了一个错误。我应该在哪里创建这个类(在 Application.java 内部???)以及之后要做什么?谢谢!!
    • @AndreyArshavin 当然感谢您的评论。据我了解,听起来您没有正确实例化Application Class。您查看过我关于Applicaion Class 的网址吗? (medium.com/droid-log/android-application-class-a8a1d64c82d1)
    【解决方案2】:

    在实际实现中使用这些:

    actual typealias PlatformContext = Activity  //Android
    
    actual typealias PlatformContext = NSObject  //iOS
    

    这是一个很好的教程来实现这一点并解决了我的问题: UserDefaults and SharedPreference in KMM

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      • 1970-01-01
      • 2016-09-05
      • 1970-01-01
      相关资源
      最近更新 更多