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

Android 如何在拦截器中访问上下文?,android,okhttp,Android,Okhttp,我想在使用拦截器时在SharedReferences上保存一些内容。 我找不到这样做的方法,因为我找不到访问拦截器上上下文的方法(因此不可能使用PreferencesManager等) 有什么想法吗 我正在使用AndroidStudio&OkHttp的最新版本 谢谢;) 您可以创建一个类,该类允许您从任何地方(即您的拦截器)检索上下文: 然后将其添加到清单中,如下所示: <application android:name="com.example.app.MyApp" 您不应该保

我想在使用拦截器时在SharedReferences上保存一些内容。 我找不到这样做的方法,因为我找不到访问拦截器上上下文的方法(因此不可能使用PreferencesManager等)

有什么想法吗

我正在使用AndroidStudio&OkHttp的最新版本


谢谢;)

您可以创建一个类,该类允许您从任何地方(即您的拦截器)检索上下文:

然后将其添加到清单中,如下所示:

<application
    android:name="com.example.app.MyApp"

您不应该保留上下文的静态实例,因为它会导致内存泄漏。相反,您可以稍微更改您的体系结构,以便能够将上下文作为参数发送给拦截器

// 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();
    }
}
然后可以在拦截器类中使用该上下文实例

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);

    }
}


祝你好运

使用依赖项注入并通过构造函数提供
共享引用
(而不是
上下文
-在您的示例中,
拦截器
需要
共享引用
)实例:

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将其注入父类

  • 用Hilt注入父类
  • 将应用程序上下文添加到父类构造函数
  • 将上下文作为参数发送到拦截器

  • 这不会导致内存泄漏吗?将应用程序对象存储在静态变量中。通过构造函数将上下文传递给拦截器是更好的解决方案,不会导致内存泄漏。将MyApp设为静态不是一个好主意。如果从模块项目调用API会怎么样?模块项目没有应用程序类。应避免此解决方案,因为它可能导致内存泄漏。
    应用程序
    已经是一个单例-将其存储在
    静态
    字段中不会导致内存泄漏。对于其他
    上下文
    源(活动、服务),情况并非如此,其中存储
    静态
    引用可能会导致内存泄漏,但以这种方式使用
    应用程序
    是可以的。
    // 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();
        }
    }
    
    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);
    
        }
    }
    
    class CookieInterceptor implements Interceptor {
    
        private final SharedPreferences prefs;
    
        CookieInterceptor(SharedPreferences prefs) {
            this.prefs = prefs;
        }
    
        @Override public Response intercept(Chain chain) throws IOException {
            prefs.getXXX(...)
        }
    
    }
    
    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)
    
    }}