我面临着一个相当简单的局面,但我无法绕过它。也许OkHttp大师可以照亮我的道路。
我在我的Android应用中使用Picasso,Retrofit和OkHttp用于多种用途。好极了!。正如我所读,开发人员应该努力保持OkHttpClient(如此处所示)。
考虑到这种方法,我希望我的任何HTTP调用(无论是API调用,图像加载,资源下载)都可以:
当然,我会为Retrofit和Picasso重复使用相同的客户端。
我正在考虑的一条路线是混合使用Authenticator和应用Interceptor。 Authenticator应该捕获HTTP401,但是我可以在此期间让它发出另一个同步请求,存储令牌并激活新的拦截器吗?
答案 0 :(得分:4)
看起来我自己找到了解决这个问题的解决方案,所以让我们分享每个人的知识。
为此,OkHttp已经提供了所有必要的钩子。
这也意味着Authenticator
处理HTTP以设置你的令牌(在另一个Android服务中完成)。
okHttpClient.setAuthenticator(new Authenticator() {
@Override
public Request authenticate(Proxy proxy, Response response) {
AccountManager accountManager = AccountManager.get(context);
Account[] accounts = accountManager.getAccountsByType(Authenticator.ACCOUNT_TYPE);
// No account, do not even try to authenticate
if (accounts.length == 0) {
Log.i(TAG, "... But we dont have any account yet, so I will just back off for now.");
return null;
}
Account account = accounts[0];
try {
final String mCurrentToken = accountManager.blockingGetAuthToken(account, "", false);
// For now, we just re-install blindly an interceptor
okHttpClient.interceptors().clear();
Log.i(TAG, "... Installing interceptor after authentication");
okHttpClient.interceptors().add(new Interceptor() {
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request newReq = request.newBuilder()
.addHeader("Authorization", mCurrentToken)
.build();
Response response = chain.proceed(newReq);
return response;
}
});
Log.i(TAG, "Install temporary auth token in request");
return response.request().newBuilder()
.addHeader("Authorization", mCurrentToken)
.build();
} catch (OperationCanceledException e) {
Log.e(TAG, "Interrupted exception");
return null;
} catch (AuthenticatorException e) {
Log.e(TAG, "Authentication error");
return null;
} catch (IOException e) {
Log.e(TAG, "IO Error");
return null;
}
}
@Override
public Request authenticateProxy(Proxy proxy, Response response) {
return null; // Null indicates no attempt to authenticate.
}
})
有了这个,只需在Picasso和Retrofit中使用这个OkClient。