How to set a priority of retrofit requests
How to set a priority of retrofit requests
I have ViewPager
and in this ViewPager there are 4 fragments. Sorry but I can't to add a code, because that would be very big. Each of my fragments on create does asynchronous retrofit request to server. I have access_token
and refresh_token
too. So when my access_token
expires I need to do a call using refresh_token
to update my access_token
. So when I launch my application it opens viewPager with my 4 fragments doing asynchronous requests. That means 4 requests at a time. And when my access_token is expired and I'm launching my app, all the fragments try to update the access token using refresh token. Turns out that one fragment updates the access_token (after the update refresh_token changes) other fragments try to update the token too, but I'm getting 401 because 1 fragment already updated the token and other fragments try to update the access_token using old refresh token.
ViewPager
access_token
refresh_token
access_token
refresh_token
access_token
Here is the example of one request.
Call<ResponseBody> getChatImageCall = apiClient.getImages(cutMessage, CHAT_IMAGE_TYPE);
getChatImageCall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, final Response<ResponseBody> response) {
if (response.isSuccessful()) {
try {
messagesAdapter.addToStart(MessagesFixtures.getImageBytesMessage(response.body().bytes(), id), true);
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getActivity(), "Something went wrong", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Toast.makeText(getActivity(), "An error occurred", Toast.LENGTH_SHORT).show();
}
});
Here is the token update request part
public class RefreshToken {
Context context;
TokenUpdaterCallback tokenUpdaterCallback;
ApiClient apiClient = ApiClient.getInstance();
public RefreshToken(Context context, TokenUpdaterCallback tokenUpdaterCallback) {
this.context = context;
this.tokenUpdaterCallback = tokenUpdaterCallback;
}
public void updateToken() {
//Perform this call if access token is expired
SupportObjToken supportObjToken = new SupportObjToken();
supportObjToken.setGrantType("refresh_token");
supportObjToken.setClientId(SharedPreferencesManager.getInstance().getUserData().getClientId());
supportObjToken.setClientSecret(SharedPreferencesManager.getInstance().getUserData().getClientSecret());
supportObjToken.setRefreshToken(SharedPreferencesManager.getInstance().getUserData().getRefreshToken());
Call<RefreshTokenActivation> newToken = apiClient.newToken(supportObjToken);
newToken.enqueue(new Callback<RefreshTokenActivation>() {
@Override
public void onResponse(Call<RefreshTokenActivation> call, Response<RefreshTokenActivation> response) {
if (response.isSuccessful()) {
String newAccessToken = response.body().getAccessToken();
String newRefreshToken = response.body().getRefreshToken();
UserData userData = SharedPreferencesManager.getInstance().getUserData();
SharedPreferencesManager.getInstance().removeUser();
userData.setAccessToken(newAccessToken);
userData.setRefreshToken(newRefreshToken);
SharedPreferencesManager.getInstance().setUser(userData);
tokenUpdaterCallback.updateToken();
} else {
if (response.code() == 401) {
//Perform this call if refresh token is expired
Activity activity = (Activity) context;
MainActivity mainActivity = (MainActivity) activity;
mainActivity.logOut();
Toast.makeText(activity, "You logged on other hardware", Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onFailure(Call<RefreshTokenActivation> call, Throwable t) {
Toast.makeText(context, "Response is not successful", Toast.LENGTH_SHORT).show();
}
});
}
}
tokenUpdaterCallback is a simple interface with updateToken() method. So you don't need this.
request_token
Wait I'll add the token update code part
– Name Surname
Jul 2 at 10:13
From where you calling
updateToken
method and what error you are getting when your access_token
is expired– Brijesh Joshi
Jul 2 at 10:18
updateToken
access_token
When I'm doing request from fragment and get 401, I'm call this refresh token class. The update token method is when I'm updating my token I'm doing request from fragment one more time, else when it gets 401 and updates then nothing happens)
– Name Surname
Jul 2 at 10:23
Okay can you add a flag in your
RefreshToken
class , for example requesting_token
set it true when you entering the updatetoken method. and set it false when your api call is done with success/failure. and when calling the updateToken api check for that variable– Brijesh Joshi
Jul 2 at 10:52
RefreshToken
requesting_token
1 Answer
1
public class RefreshToken {
Context context;
TokenUpdaterCallback tokenUpdaterCallback;
ApiClient apiClient = ApiClient.getInstance();
boolean isLoading = false;
public RefreshToken(Context context, TokenUpdaterCallback tokenUpdaterCallback) {
this.context = context;
this.tokenUpdaterCallback = tokenUpdaterCallback;
}
public void updateToken() {
if (!isLoading) {
isLoading = true;
//Perform this call if access token is expired
SupportObjToken supportObjToken = new SupportObjToken();
supportObjToken.setGrantType("refresh_token");
supportObjToken.setClientId(SharedPreferencesManager.getInstance().getUserData().getClientId());
supportObjToken.setClientSecret(SharedPreferencesManager.getInstance().getUserData().getClientSecret());
supportObjToken.setRefreshToken(SharedPreferencesManager.getInstance().getUserData().getRefreshToken());
Call<RefreshTokenActivation> newToken = apiClient.newToken(supportObjToken);
newToken.enqueue(new Callback<RefreshTokenActivation>() {
@Override
public void onResponse(Call<RefreshTokenActivation> call, Response<RefreshTokenActivation> response) {
if (response.isSuccessful()) {
String newAccessToken = response.body().getAccessToken();
String newRefreshToken = response.body().getRefreshToken();
UserData userData = SharedPreferencesManager.getInstance().getUserData();
SharedPreferencesManager.getInstance().removeUser();
userData.setAccessToken(newAccessToken);
userData.setRefreshToken(newRefreshToken);
SharedPreferencesManager.getInstance().setUser(userData);
tokenUpdaterCallback.updateToken();
} else {
if (response.code() == 401) {
//Perform this call if refresh token is expired
Activity activity = (Activity) context;
MainActivity mainActivity = (MainActivity) activity;
mainActivity.logOut();
Toast.makeText(activity, "You logged on other hardware", Toast.LENGTH_SHORT).show();
}
isLoading = false;
}
}
@Override
public void onFailure(Call<RefreshTokenActivation> call, Throwable t) {
Toast.makeText(context, "Response is not successful", Toast.LENGTH_SHORT).show();
isLoading = false;
}
});
}
}
}
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
From where are you calling that
request_token
API can you please share that code– Brijesh Joshi
Jul 2 at 10:02