android - Koin + Retrofit 在运行时添加标题
问题描述
我在 MVVM 架构中有一个基于硬币和改造的项目。我想在注册此项目后使用“viewmodel”打印数据并在运行时将“token”的值添加到标题中。但我无法提供获取我保存在 SharedPreferences 中的令牌所需的上下文结构。我怎样才能以最干净的形式处理它?
fun createNetworkClient(baseUrl: String) =
retrofitClient(baseUrl, httpClient())
private fun httpClient(): OkHttpClient {
val httpLoggingInterceptor = HttpLoggingInterceptor(HttpLoggingInterceptor.Logger.DEFAULT)
val clientBuilder = OkHttpClient.Builder()
if (BuildConfig.DEBUG) {
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
clientBuilder.addInterceptor(httpLoggingInterceptor)
}
clientBuilder.addInterceptor { chain ->
val newRequest = chain.request().newBuilder()
.addHeader( //I can't get token because there is no context here.
"Authorization", "Bearer ${PreferencesHelper.getInstance(context).token.toString()}"
)
.build()
chain.proceed(newRequest)
}
clientBuilder.readTimeout(120, TimeUnit.SECONDS)
clientBuilder.writeTimeout(120, TimeUnit.SECONDS)
return clientBuilder.build()
}
private fun retrofitClient(baseUrl: String, httpClient: OkHttpClient): Retrofit =
Retrofit.Builder()
.baseUrl(baseUrl)
.client(httpClient)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
应用模块
val appModule = module {
single {
androidApplication().getSharedPreferences("PREFERENCES", android.content.Context.MODE_PRIVATE)
}
single { createNetworkClient(BuildConfig.BASE_URL) }
single { (get() as Retrofit).create(Api::class.java) }
viewModel {
ContactViewModel(get())
}
}
我的联系活动
private val contactList: ContactViewModel by viewModel()
override fun onCreate(savedInstanceState: Bundle?) {
viewModel = contactList
super.onCreate(savedInstanceState)
binding.adapter = ContactAdapter(this)
binding.layoutManager = LinearLayoutManager(this)
contactList.getContactList()
contactList.contactListLiveData.observe(this, Observer { list ->
if (list != null)
binding.adapter?.update(list)
})
}
解决方案
您可以创建一个 Koin 模块来提供共享首选项:
val sharedPreferencesModule = module {
single {
androidApplication().getSharedPreferences("PREFERENCES", android.content.Context.MODE_PRIVATE)
}
}
然后用 Koin 将其注入到生成 Retrofit 客户端的类中。
编辑
您需要修改createNetworkClient
方法签名:
fun createNetworkClient(baseUrl: String, preferences: SharedPreferences)
然后用 Koin 注入它:
val appModule = module {
single {
androidApplication().getSharedPreferences("PREFERENCES", android.content.Context.MODE_PRIVATE)
}
single { createNetworkClient(BuildConfig.BASE_URL, get()) }
...
}
然后,您将收到在方法中注入的共享首选项,createNetworkClient
并且只需要实现从共享首选项中检索令牌的逻辑。
推荐阅读
- c++ - 在 intel 内部函数 (AVX) 中使用混合指令
- sql - 将 varchar 转换为日期 ddmmyyyy 时出错
- azure - Azure VM 无法访问端口 8080
- ios - Kingfisher + RxSwift DownsamplingImageProcessor 图像失败
- python-3.x - 从python中的元素列表中获取属性
- kubernetes - 使用 sh 命令时 Kubernetes Pod 的容器未运行
- flutter - 如何创建自定义颤振 sdk 小部件,重建颤振和使用新的小部件
- python - 在不同列上解析 JSON 的结果
- javascript - 我只需要在开始日期选择的日期选择器中显示未来一个月的日期
- python - 输入形状引起的负维度