如何在对象中获取上下文?
Posted
技术标签:
【中文标题】如何在对象中获取上下文?【英文标题】:How to get Context inside an Object? 【发布时间】: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 请检查更新的问题
【参考方案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
【讨论】:
是的,我可以在我的活动中获取令牌,但我不知道如何在改造课程中传递它。我尝试了传递令牌的方法,请查看我更新的问题(UPDATE-2) @PrathamVaidya 试试这个 谢谢你的解决方案有效,我是第一次使用改造。【参考方案2】:与其尝试将上下文存储在单例中,不如存储您要发送的标头。访问 Activity 中的上下文和共享首选项。
变化:
RetrofitClient.instance.getContext(this)
类似
RetrofitClient.instance.setAuthHeader(getSharedPreferences().getString("Header"))
【讨论】:
先生,我试过你的答案,但它给了我一个错误。请检查我更新的问题(UPDATE-2)以上是关于如何在对象中获取上下文?的主要内容,如果未能解决你的问题,请参考以下文章
在托管对象上下文中添加 NSSortDescriptor 以获取请求?