Android 改型2拦截器,仅在特定方法中使用令牌

Android 改型2拦截器,仅在特定方法中使用令牌,android,authorization,retrofit2,interceptor,okhttp3,Android,Authorization,Retrofit2,Interceptor,Okhttp3,我想在2中使用授权。我选择了截取方式,因为几乎所有的方法都需要授权,除了一个我正在获取令牌以便与其他方法一起使用的方法之外 我的问题是:我如何才能做到这一点? 我将访问令牌存储在SharedReferences中。我的第一个想法是:“我可以在改型客户端类中检索它,这取决于令牌是否为null或它是否有值创建合适的改型实例”(无论是否向其添加.client()) 不幸的是,这并不容易,因为需要Context来获取首选项 我不知道如何将它传递到client类中,也不知道如何在内部访问它 这是我的cli

我想在
2
中使用
授权
。我选择了截取方式,因为几乎所有的方法都需要授权,除了一个我正在获取令牌以便与其他方法一起使用的方法之外

我的问题是:我如何才能做到这一点?

我将访问令牌存储在
SharedReferences
中。我的第一个想法是:“我可以在
改型客户端
类中检索它,这取决于令牌是否为null或它是否有值创建合适的
改型
实例”(无论是否向其添加
.client()

不幸的是,这并不容易,因为需要
Context
来获取首选项

我不知道如何将它传递到
client
类中,也不知道如何在内部访问它

这是我的
client
class:

public class RetrofitClient {

    public static final String BASE_URL = "http://localhost";
    public static Retrofit retrofit = null;

    private RetrofitClient() {
        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                //.client(getRequestHeader())
                .build();
    }

    /*OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request newRequest = chain.request().newBuilder()
                    .addHeader("Authorization", "Bearer" + )
        }
    })*/

    public static synchronized Retrofit getInstance() {
        if (retrofit == null) {

            retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create()).build();
        }
        return retrofit;
    }

    public Api getApi() {
        return retrofit.create(Api.class);
    }
}
我的
getRequestHeader()
是以前设置超时的方法

我想创建这样的实例:

private RetrofitClient() {
            tokenService.token = null;
            tokenService.readToken(ApplicationContext.getInstance());


            if (tokenService.token == null) {
                retrofit = new Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .build();
            } else {
                retrofit = new Retrofit.Builder()
                        .baseUrl(BASE_URL)
                        .addConverterFactory(GsonConverterFactory.create())
                        .client(client) //I have interceptor here with access token
                        .build();
            }
        }
然后:
client.getInstance().create(Api.class).getToken()
//获取令牌
client.getInstance().create(Api.class).someMethod()
//当我获取令牌时


这是一种好方法吗?

只需将SharedReferences作为构造函数参数添加到客户端或其他应用程序中,具体取决于具体情况,您可以按以下方式执行:

首先使用singleton实例创建一个首选项类

偏好

然后在客户端类中进行如下更改:

改造客户


您可以使用应用程序处于活动状态时可用的应用程序上下文。请从应用程序类获取它:

public class MyApp extends Application {
    private static MyApp instance;
    @Override
    public void onCreate() {
    super.onCreate();
    instance = this;
    //other code
}
public static MyApp getInstance() {
    return instance;
}
然后简单地使用
MyApp.getInstance()
获取您需要的上下文。通过这种方法,您可以实现您之前所想的,并在
客户端
类中获取共享引用

别忘了将应用程序类添加到清单中

更新: 你们只创建了一次改造实例,所以若你们在拥有令牌的时候创建它,你们将在应用程序运行时一直使用它。 我认为,好的做法是检查您的拦截器中的令牌。类似于以下内容:

new Interceptor() {
        @Override
        public Response intercept(@NonNull Chain chain) throws IOException {
            Request request = chain.request();
            if (tokenService.token == null) {
                return chain.proceed(request);
            } else {
                return chain.proceed(request.newBuilder().addHeader("Authorization", "Bearer" + tokenService.token).build());
            }
        }
    }

另外,我不知道您的令牌服务是如何工作的。但是请记住,如果您在注销时清除了令牌,最好是始终签入令牌的共享首选项。因为您的令牌服务可能会保留令牌字符串,即使在共享首选项中清除了它。

还有最后一个简单的问题。如果我调用
InversionClient.getInstance().create(Api.class).getToken()
然后
安装client.getInstance().create(Api.class).someMethod())
哪个需要令牌?它会正常工作吗?请在我的编辑中检查构造函数的修改。@SkypeDogg我更新了我的答案,希望现在清楚class
TokenService
有一个令牌字符串字段和三个方法:
saveToken()
readToken()
clearToken()
但每次打开应用程序时,我都会要求使用PIN码的令牌,但我会使用下一种方法,除非令牌码为
200
,否则它会通知错误的PIN码。每次新令牌码返回时,它都会覆盖旧PIN码,所以我希望不会有任何错误,即使没有
clearToken()
method@SkypeDogg太好了,希望我能帮你一点忙
public class MyApp extends Application {
    private static MyApp instance;
    @Override
    public void onCreate() {
    super.onCreate();
    instance = this;
    //other code
}
public static MyApp getInstance() {
    return instance;
}
new Interceptor() {
        @Override
        public Response intercept(@NonNull Chain chain) throws IOException {
            Request request = chain.request();
            if (tokenService.token == null) {
                return chain.proceed(request);
            } else {
                return chain.proceed(request.newBuilder().addHeader("Authorization", "Bearer" + tokenService.token).build());
            }
        }
    }