对于我的项目,我正在对API调用进行改装。
对于身份验证,我使用JWT令牌。
用于存储和刷新我使用的令牌流
Google's AccountManager
.
ApiService类是一个单例,我构建如下:
private ApiService(AccountManager accountManager) {
mAccountManager = accountManager;
build();
}
public static synchronized ApiService getInstance(AccountManager accountManager) {
if (mInstance == null) {
mInstance = new ApiService(accountManager);
}
return mInstance;
}
在本课程中,我正在构建OkHttp3客户端和改装服务。
当服务器响应质询时,Okhttp3有一个很好的方法,所以我将其设置为:
OkHttpClient client = new OkHttpClient.Builder()
.authenticator(new ApiAuthenticator(mAccountManager))
如您所见,我正在设置Okhttp3验证器的自定义实现,如下所示:
public class ApiAuthenticator implements Authenticator {
private static final String TAG = "ApiAuthenticator";
private AccountManager accountManager;
ApiAuthenticator(AccountManager accountManager) {
this.accountManager = accountManager;
}
private static int responseCount(Response response) {
int result = 1;
while ((response = response.priorResponse()) != null) {
result++;
}
return result;
}
@Nullable
@Override
public Request authenticate(@NonNull Route route, @NonNull Response response) throws IOException {
if (response.request().url().encodedPath().startsWith("login_check") || response.request().url().encodedPath().startsWith("token"))
return null;
if (responseCount(response) >= 2) {
return null;
}
for (Challenge challenge : response.challenges()) {
if (challenge.scheme().equals("Bearer")) {
Account[] accounts = accountManager.getAccountsByType(AuthConstants.ACCOUNT_TYPE);
if (accounts.length != 0) {
String oldToken = accountManager.peekAuthToken(accounts[0], AuthConstants.AUTHTOKEN_TYPE_FULL_ACCESS);
if (oldToken != null) {
accountManager.invalidateAuthToken(AuthConstants.ACCOUNT_TYPE, oldToken);
}
try {
String token = accountManager.blockingGetAuthToken(accounts[0], AuthConstants.AUTHTOKEN_TYPE_FULL_ACCESS, false);
if (token == null) {
accountManager.removeAccount(accounts[0], null, null);
}
if (token != null) {
Request.Builder builder = response.request().newBuilder();
return builder.header("Authorization", "Bearer " + token).build();
}
} catch (OperationCanceledException | AuthenticatorException e) {
e.printStackTrace();
Log.d(TAG, e.getLocalizedMessage());
}
}
}
}
return null;
}
}
我的某些函数存储库如下所示:
public class ApiCheckinRepository implements CheckinRepository {
private AccountManager accountManager;
public ApiCheckinRepository(AccountManager accountManager) {
this.accountManager = accountManager;
}
@Override
public Observable<Response<Message>> checkin(QrCode qrCode) {
return ApiService.getInstance(accountManager).checkin(qrCode);
}
}
但现在我发现accountManager依赖性导致内存泄漏,我再也看不到解决方案了。。。