如何访问拦截器中的上下文?

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。

  1. 使用 Hilt
  2. 注入父 class
  3. 将应用程序上下文添加到父 class 构造函数
  4. 将上下文作为参数发送给拦截器
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)

}}