如何访问拦截器中的上下文?
How to access context in a Interceptor?
我想在使用拦截器时在 SharedPreferences 上保存一些内容。
我找不到一种方法来做到这一点,因为我找不到一种方法来访问拦截器上的上下文(因此无法使用 PreferencesManager 等)。
public class CookieInterceptor implements Interceptor {
@Override public Response intercept(Chain chain) throws IOException {
PreferenceManager.getDefaultSharedPreferences(Context ??)
}}
有什么想法吗?
我正在使用 AndroidStudio 和最新版本的 OkHttp。
谢谢 ;)
您可以创建一个 class 允许您从任何地方检索上下文(即您的拦截器):
public class MyApp extends Application {
private static MyApp instance;
public static MyApp getInstance() {
return instance;
}
public static Context getContext(){
return instance;
}
@Override
public void onCreate() {
instance = this;
super.onCreate();
}
}
然后像这样将其添加到您的清单中:
<application
android:name="com.example.app.MyApp"
然后在你的拦截器中,这样做:
PreferenceManager.getDefaultSharedPreferences(MyApp.getContext());
你不应该保留上下文的静态实例,因为它会导致内存泄漏。相反,您可以稍微更改架构,以便能够将上下文作为参数发送给拦截器。
// in your network operations class
// where you create OkHttp instance
// and add interceptor
public class NetworkOperations {
private Context context;
public NetworkOperations(Context context) {
this.context = context;
OkHttpClient client = new OkHttpClient.Builder()
// ... some code here
.addInterceptor(new CookieInterceptor(context))
// ... some code here
.build();
}
}
然后您可以在拦截器中使用该上下文实例 class。
public class CookieInterceptor implements Interceptor {
private Context context;
public CookieInterceptor(Context context) {
this.context = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
PreferenceManager.getDefaultSharedPreferences(context);
}
}
祝你好运!
使用依赖注入并通过构造函数提供 SharedPreferences
(不是 Context
- 在您的示例中,您的 Interceptor
需要 SharedPreferences
)实例:
class CookieInterceptor implements Interceptor {
private final SharedPreferences prefs;
CookieInterceptor(SharedPreferences prefs) {
this.prefs = prefs;
}
@Override public Response intercept(Chain chain) throws IOException {
prefs.getXXX(...)
}
}
我自己也为此苦苦挣扎了好几天,最终解决方案很简单,就是使用 Hilt 将其注入父级 class。
- 使用 Hilt
注入父 class
- 将应用程序上下文添加到父 class 构造函数
- 将上下文作为参数发送给拦截器
class RetrofitWithCookie @Inject constructor(
@ApplicationContext context: Context
) {
private val mContext = context
fun createRetrofit(): Retrofit {
val client: OkHttpClient
val builder = OkHttpClient.Builder()
builder.addInterceptor(CookieInterceptor(mContext))
client = builder.build()
return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
}
public class CookieInterceptor implements Interceptor {
private Context context;
public CookieInterceptor(Context context) {
this.context = (Context) context;
}
@Override public Response intercept(Chain chain) throws IOException {
PreferenceManager.getDefaultSharedPreferences(Context)
}}
我想在使用拦截器时在 SharedPreferences 上保存一些内容。 我找不到一种方法来做到这一点,因为我找不到一种方法来访问拦截器上的上下文(因此无法使用 PreferencesManager 等)。
public class CookieInterceptor implements Interceptor {
@Override public Response intercept(Chain chain) throws IOException {
PreferenceManager.getDefaultSharedPreferences(Context ??)
}}
有什么想法吗?
我正在使用 AndroidStudio 和最新版本的 OkHttp。
谢谢 ;)
您可以创建一个 class 允许您从任何地方检索上下文(即您的拦截器):
public class MyApp extends Application {
private static MyApp instance;
public static MyApp getInstance() {
return instance;
}
public static Context getContext(){
return instance;
}
@Override
public void onCreate() {
instance = this;
super.onCreate();
}
}
然后像这样将其添加到您的清单中:
<application
android:name="com.example.app.MyApp"
然后在你的拦截器中,这样做:
PreferenceManager.getDefaultSharedPreferences(MyApp.getContext());
你不应该保留上下文的静态实例,因为它会导致内存泄漏。相反,您可以稍微更改架构,以便能够将上下文作为参数发送给拦截器。
// in your network operations class
// where you create OkHttp instance
// and add interceptor
public class NetworkOperations {
private Context context;
public NetworkOperations(Context context) {
this.context = context;
OkHttpClient client = new OkHttpClient.Builder()
// ... some code here
.addInterceptor(new CookieInterceptor(context))
// ... some code here
.build();
}
}
然后您可以在拦截器中使用该上下文实例 class。
public class CookieInterceptor implements Interceptor {
private Context context;
public CookieInterceptor(Context context) {
this.context = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
PreferenceManager.getDefaultSharedPreferences(context);
}
}
祝你好运!
使用依赖注入并通过构造函数提供 SharedPreferences
(不是 Context
- 在您的示例中,您的 Interceptor
需要 SharedPreferences
)实例:
class CookieInterceptor implements Interceptor {
private final SharedPreferences prefs;
CookieInterceptor(SharedPreferences prefs) {
this.prefs = prefs;
}
@Override public Response intercept(Chain chain) throws IOException {
prefs.getXXX(...)
}
}
我自己也为此苦苦挣扎了好几天,最终解决方案很简单,就是使用 Hilt 将其注入父级 class。
- 使用 Hilt 注入父 class
- 将应用程序上下文添加到父 class 构造函数
- 将上下文作为参数发送给拦截器
class RetrofitWithCookie @Inject constructor(
@ApplicationContext context: Context
) {
private val mContext = context
fun createRetrofit(): Retrofit {
val client: OkHttpClient
val builder = OkHttpClient.Builder()
builder.addInterceptor(CookieInterceptor(mContext))
client = builder.build()
return Retrofit.Builder()
.baseUrl(BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build()
}
}
public class CookieInterceptor implements Interceptor {
private Context context;
public CookieInterceptor(Context context) {
this.context = (Context) context;
}
@Override public Response intercept(Chain chain) throws IOException {
PreferenceManager.getDefaultSharedPreferences(Context)
}}