【发布时间】:2019-11-09 04:07:22
【问题描述】:
我正在使用改造来获取一些数据,为此我在 Header 中传递了一个令牌以进行身份验证。 我想从我的改造客户端对象中的共享首选项中获取令牌,但我不知道如何?
我尝试使用函数在对象中获取上下文,但它给了我警告
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()
}
})
我想从 Shared Preferences 中获取令牌并将其用作我的请求的标头,并且我知道要访问 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
}
}
但它给出了错误:注解参数必须是编译时常量
【问题讨论】:
-
调用
getProductsForSlide方法的代码在哪里?你可以在那里访问 SharePreferences -
你最好使用 dagger2 或添加拦截器或通过参数传递标头
-
检查对您有帮助的项目。 github.com/zigic88/Dagger2-Retrofit
-
如果你想从 Shared 中获取数据而不需要对代码进行重大更改,你可以简单地通过扩展应用程序类的静态方法来获取上下文,然后创建 sharedpreferences 对象。
-
@Blundell 请检查更新的问题
标签: android kotlin jwt retrofit token