我正在使用 retrofit 来获取一些数据,为此我在 header 中传递了一个 token 以进行身份验证。 我想从 Retrofit Client 对象的共享首选项中获取 token ,但我不知道该怎么做?
我试图使用一个函数在对象中获取上下文,但它给了我警告
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>
}
[更新] 这是我的 Activity 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()
}
})
我想从 Shared Preferences 获取 token 并将其用作我的请求的 header ,我知道要访问 Shared Preferences 我们需要一个上下文。如何获取 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
}
}
但它给出错误:An annotation argument must be a compile-time constant
最佳答案
尝试在您的 Activity 中获取 token (您可以使用 Activity 的上下文并从共享首选项中获取 token )并将此 token 传递给您的改造类。
同时尝试阅读一些有关依赖注入(inject)、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>
}
在您的 Activity 中:
val prefToken = // get it from prefences
val token = "Bearer " + prefToken
关于android - 如何获取对象内部的上下文?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56785889/