Android 是否在验证器中设置SharedReference?

Android 是否在验证器中设置SharedReference?,android,retrofit,retrofit2,okhttp,okhttp3,Android,Retrofit,Retrofit2,Okhttp,Okhttp3,我用的是安卓系统。我使用SharedReferences存储身份验证令牌 为了刷新身份验证令牌,我使用验证器类 现在,我需要能够在SharedReferences中设置新的身份验证令牌,但是,为了做到这一点,SharedReferences需要一个上下文 当我没有上下文时,如何从身份验证器类设置新的(刷新的)身份验证令牌 这是我的验证器类: public class TokenAuthenticator implements Authenticator { private String

我用的是安卓系统。我使用
SharedReferences
存储身份验证令牌

为了刷新身份验证令牌,我使用
验证器

现在,我需要能够在
SharedReferences
中设置新的身份验证令牌,但是,为了做到这一点,
SharedReferences
需要一个上下文

当我没有上下文时,如何从
身份验证器
类设置新的(刷新的)身份验证令牌

这是我的验证器类:

public class TokenAuthenticator implements Authenticator {
    private String authToken;

    public TokenAuthenticator(String authToken) {
        this.authToken = authToken;
    }

    @Override
    public Request authenticate(Route route, Response response) throws IOException {
        if (responseCount(response) >= 3) {
            return null;
        }

        ApiInterface apiService = ApiClient.createService(ApiInterface.class, authToken);
        Call<BasicResponse> call = apiService.refreshAuthToken();
        BasicResponse apiResponse = call.execute().body();

        String newToken = apiResponse.getData().getToken();

        // Set the new token in shared preferences (how to get context?)
        SharedPreferences sp = getSharedPreferences(context);
        sp.edit().putString("AUTH_TOKEN", token).apply();

        return response.request().newBuilder()
                .header("Authorization", "Bearer " + newToken)
                .build();
    }

    private int responseCount(Response response) {
        int result = 1;
        while ((response = response.priorResponse()) != null) {
            result++;
        }
        return result;
    }

}
公共类令牌验证器实现验证器{
私有字符串身份验证令牌;
公共令牌身份验证器(字符串authToken){
this.authToken=authToken;
}
@凌驾
公共请求身份验证(路由、响应)引发IOException{
如果(响应计数(响应)>=3){
返回null;
}
ApiInterface ApisService=ApiClient.createService(ApiInterface.class,authToken);
Call Call=apiService.refreshAuthToken();
BasicResponse apiResponse=call.execute().body();
字符串newToken=apiResponse.getData().getToken();
//在共享首选项中设置新令牌(如何获取上下文?)
SharedReferences sp=GetSharedReferences(上下文);
sp.edit().putString(“AUTH_TOKEN”,TOKEN).apply();
返回response.request().newBuilder()
.标题(“授权”、“持票人”+newToken)
.build();
}
私有int responseCount(响应){
int结果=1;
while((response=response.priorResponse())!=null){
结果++;
}
返回结果;
}
}
下面是调用Authenticator类的位置:

public class ApiClient {

    public static final String API_URL = "http://www.user324211.com/";

    private static OkHttpClient.Builder httpClient =
            new OkHttpClient.Builder();

    private static Retrofit.Builder builder =
            new Retrofit.Builder()
                    .baseUrl(API_URL)
                    .addConverterFactory(GsonConverterFactory.create());

    private static Retrofit retrofit = builder.build();

    public static Retrofit getRetrofit() {
        return retrofit;
    }

    public static <S> S createService(Class<S> serviceClass) {
        return createService(serviceClass, null);
    }

    public static <S> S createService(Class<S> serviceClass, final String authToken) {
        if (authToken != null) {
            TokenAuthenticator tokenAuthenticator = new TokenAuthenticator(authToken);
            httpClient.authenticator(tokenAuthenticator);
        }

        builder.client(httpClient.build());
        retrofit = builder.build();

        return retrofit.create(serviceClass);
    }

}
公共类ApiClient{
公共静态最终字符串API_URL=”http://www.user324211.com/";
私有静态OkHttpClient.Builder httpClient=
新建OkHttpClient.Builder();
私人静态改装=
新的改型.Builder()
.baseUrl(API_URL)
.addConverterFactory(GsonConverterFactory.create());
私有静态改装改装=builder.build();
公共静态改装GetRefundation(){
回流改造;
}
公共静态S createService(类serviceClass){
返回createService(serviceClass,null);
}
公共静态S createService(类serviceClass,最终字符串authToken){
if(authToken!=null){
TokenAuthenticator TokenAuthenticator=新的TokenAuthenticator(authToken);
httpClient.authenticator(令牌认证器);
}
builder.client(httpClient.build());
改装=builder.build();
返回改装。创建(serviceClass);
}
}

有几种方法可以做到这一点

我建议您创建一个应用程序类,并在应用程序内部创建一个方法 调用它getContext(),则该方法可以从任何地方访问

您可以获得类似App.getContext()的上下文

范例

package YOUR_PACKAGE_NAME;

import android.app.Application;
import android.content.Context;

public class App extends Application
{
    private static Context context;

    @Override
    public void onCreate()
    {
        super.onCreate();

        context = getApplicationContext();
    }

    public static Context GetContext()
    {
        return context;
    }
}
您可以创建这样的单例共享引用

只需再添加一个参数

public TokenAuthenticator(Context context,String authToken) {
        this.authToken = authToken;
        this.mContext = context;
}
用法

编辑 如果没有上下文调用,只需传递SharedReferences即可

public TokenAuthenticator(SharedPreferences shared,String authToken) {
       this.authToken = authToken;
       this.mShared = shared;
}

您可以通过提供一个如何使用此构造函数的示例来改进您的答案。更好一点。您应该显示包含这最后一行代码的类和方法,以便清楚地知道这是什么。@ZeroOne不幸的是,authenticator类是从一个没有给出上下文的类调用的。也许您可以将SharedReferences作为参数传递“也许您可以将SharedReferences作为参数传递”这可能是一个好的解决方案。OP仍然需要弄清楚如何获得SharedReferences引用以传递给构造函数。
静态
变量很少是正确的解决方案。@code学徒是的,您是对的,但这是应用程序类,因此静态变量不会泄漏泄漏泄漏是最不重要的问题。我更关心的是如何教授正确的编码实践。这是一个全局解决方案,在大型应用程序中,这可能是必需的,而静态从来都不是“必需的”。您可以始终传递参数。您在哪里创建
TokenAuthenticator
?@code学徒添加了代码。您在哪里调用createService()?@code学徒每当我需要从服务器获取数据时,都会在我的应用程序中调用。在我上面的代码中,它用于
TokenAuthenticator
类。“在我上面的代码中,它用于
TokenAuthenticator
类。”我感到困惑。
TokenAuthenticator
在哪里使用
ApiClient.createService()
?我在你发布的代码中没有看到这一点。从我看来,依赖性是另一种方式。现在我们需要提高一个层次。谁调用
getService()
public TokenAuthenticator(SharedPreferences shared,String authToken) {
       this.authToken = authToken;
       this.mShared = shared;
}