我正在使用翻新来获取一些数据,为此,我在身份验证标头中传递了令牌。 我想从Retrofit Client对象中的Shared Preferences中获取令牌,但是我不知道该怎么做?
我尝试使用函数在对象中获取上下文,但随后给我警告
Do not place Android context classes in static fields (static reference to RetrofitClient which has field context pointing to Context); this is a memory leak (and also breaks Instant Run) less...
我也尝试在改造界面中获取上下文,但没有警告就获取了上下文,但是我不知道从何处获取共享首选项。
interface Api {
var context:Context;
@FormUrlEncoded
@POST("getMerchantProductsSlideContent")
fun getProductsForSlide(
//Don't know how to get value from shared refercne to this header
@Header("Authentication: Bearer ")
@Field("token") token:String,
@Field("deviceId") deviceId:String,
@Field("content_receiver") content_receiver:String,
@Field("content_type") content_type:String,
@Field("data") data:Array<String>
):Call<DefaultResponse>
fun getContext(mContext:Context){
context = mContext
}
}
这是retrofitClient.kt
object RetrofitClient {
private val AUTH = "Bearer $token"
private const val BASE_URL = "http://192.168.1.5/Projects/Sitapuriya/public/"
private val okHttpClient = OkHttpClient.Builder()
.addInterceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
.addHeader("Authorization", AUTH)
.method(original.method(), original.body())
val request = requestBuilder.build()
chain.proceed(request)
}.build()
val instance: Api by lazy{
val retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build()
retrofit.create(Api::class.java)
}
}
这是我的改造界面
interface Api {
@FormUrlEncoded
@POST("getMerchantProductsSlideContent")
fun getProductsForSlide(
@Field("token2") token2:String,
@Field("deviceId") deviceId:String,
@Field("content_receiver") content_receiver:String,
@Field("content_type") content_type:String,
@Field("data") data:Array<String>
):Call<DefaultResponse>
}
[更新]这是我的活动n,我称其为改造
val data = arrayOf(merchantId)
RetrofitClient.instance.getContext(this)
RetrofitClient.instance.getProductsForSlide(
token,
deviceId,
"MERCHANT",
"MERCHANT_VIEW_BASIC",
data
).enqueue(object:Callback<DefaultResponse>{
override fun onFailure(call: Call<DefaultResponse>, t: Throwable) {
Toast.makeText(applicationContext,"ERROR: ${t.message}",Toast.LENGTH_LONG).show()
}
override fun onResponse(
call: Call<DefaultResponse>,
response: retrofit2.Response<DefaultResponse>
) {
Toast.makeText(applicationContext,"SUCCESS: ${response.body()?.content}",Toast.LENGTH_LONG).show()
}
})
我想从共享首选项中获取令牌并将其用作我的请求的标头,并且我知道要访问共享首选项,我们需要一个上下文。如何在Object中获取上下文?
[UPDATE-2]尝试过@Blundell答案
interface Api {
var token: String
@FormUrlEncoded
@POST("getMerchantProductsSlideContent")
fun getProductsForSlide(
@Header("Authentication: Bearer $token")
@Field("token") token:String,
@Field("deviceId") deviceId:String,
@Field("content_receiver") content_receiver:String,
@Field("content_type") content_type:String,
@Field("data") data:Array<String>
):Call<DefaultResponse>
fun setAuthHeader(token2:String){
token = token2
}
}
但是它给出了错误:注释参数必须是编译时常量
答案 0 :(得分:1)
而不是尝试将上下文存储在单例中,而是存储要发送的标头。访问活动中的上下文和共享首选项。
更改:
RetrofitClient.instance.getContext(this)
类似
RetrofitClient.instance.setAuthHeader(getSharedPreferences().getString("Header"))
答案 1 :(得分:1)
尝试在活动中获取令牌(您可以使用活动的上下文并从共享的首选项中获取令牌),然后将此令牌传递给改造类。
还尝试阅读有关依赖项注入,dagger2,koin等的内容,以为您的类提供不同的依赖项
interface Api {
@FormUrlEncoded
@POST("getMerchantProductsSlideContent")
fun getProductsForSlide(
@Header("Authentication") token:String,
@Field("deviceId") deviceId:String,
@Field("content_receiver") content_receiver:String,
@Field("content_type") content_type:String,
@Field("data") data:Array<String>
):Call<DefaultResponse>
}
在您的活动中:
val prefToken = // get it from prefences
val token = "Bearer " + prefToken