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