条件下改造异步调用
Retrofit Asynchronous call on condition
我必须从 API 接收令牌,将其存储在共享首选项中并仅在 如果 令牌具有时调用 API已到期。令牌在 200000 秒后过期。
基本上我会尝试按照这些说明进行操作:
- 生成令牌并将其存储在会话中
- 存储您生成令牌的时间a.k.a当前时间
- 每当您进行 API 调用时,根据当前时间检查令牌过期时间
- 如果令牌过期时间大于当前时间,则重新验证并在后台生成新令牌
然而,第一次 API 调用是在生成令牌之前进行的,null 作为令牌传递,然后生成令牌并将其存储在共享首选项中。所以它只是第一次不起作用,然后才起作用。使用if条件和异步Retrofit调用是否有问题
这是我用来创建令牌的函数
public void getToken(){
Credentials credentials=new Credentials("public_user","public_pass");
Call<Authentication> call=service.getToken(credentials);
call.enqueue(new Callback<Authentication>() {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onResponse(Call<Authentication> call, Response<Authentication> response) {
if (response.body().getCode() != 0) {
token = response.body().getDocument();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx.getApplicationContext());
SharedPreferences.Editor editor=preferences.edit();
editor.putString("token",token).commit();
tokenExpires=Instant.now().plus(Duration.ofSeconds(200000));
long millis=tokenExpires.toEpochMilli();
editor.putLong("token_expiry_time",millis).commit();
String this_token=preferences.getString("token",null);
}
}
@Override
public void onFailure(Call<Authentication> call, Throwable t) {
}
});
}
下面是我如何调用此函数并使用它来调用 API
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
service = ApiClient.getClientStats().create(ApiInterface.class);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx.getApplicationContext());
String retrievedToken = preferences.getString("token",null);
long token_expiry_time=preferences.getLong("token_expiry_time",0);
if(retrievedToken==null || token_expiry_time==0 || token_expiry_time<=Instant.now().toEpochMilli()) {
getToken();
retrievedToken=token;
}
else {
Call<Stat> call = service.getMapData("Bearer " + retrievedToken);
call.enqueue(new Callback<Stat>() {
@Override
public void onResponse(Call<Stat> call, Response<Stat> response) {
}
}
@Override
public void onFailure(Call<Stat> call, Throwable t) {
}
});
}
当您调用 getToken() 时,改装会在另一个线程上运行它。发生这种情况时,主线程继续在 if 语句中执行,并将 null 分配给 retrieveToken,因为当时令牌为 null,这就是您拥有第一个 null 的原因。然后 retrofit 完成它 exec 并设置共享首选项。在进行其他查询之前,您可以使用 LiveData 观察结果。
我必须从 API 接收令牌,将其存储在共享首选项中并仅在 如果 令牌具有时调用 API已到期。令牌在 200000 秒后过期。 基本上我会尝试按照这些说明进行操作:
- 生成令牌并将其存储在会话中
- 存储您生成令牌的时间a.k.a当前时间
- 每当您进行 API 调用时,根据当前时间检查令牌过期时间
- 如果令牌过期时间大于当前时间,则重新验证并在后台生成新令牌
然而,第一次 API 调用是在生成令牌之前进行的,null 作为令牌传递,然后生成令牌并将其存储在共享首选项中。所以它只是第一次不起作用,然后才起作用。使用if条件和异步Retrofit调用是否有问题
这是我用来创建令牌的函数
public void getToken(){
Credentials credentials=new Credentials("public_user","public_pass");
Call<Authentication> call=service.getToken(credentials);
call.enqueue(new Callback<Authentication>() {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onResponse(Call<Authentication> call, Response<Authentication> response) {
if (response.body().getCode() != 0) {
token = response.body().getDocument();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx.getApplicationContext());
SharedPreferences.Editor editor=preferences.edit();
editor.putString("token",token).commit();
tokenExpires=Instant.now().plus(Duration.ofSeconds(200000));
long millis=tokenExpires.toEpochMilli();
editor.putLong("token_expiry_time",millis).commit();
String this_token=preferences.getString("token",null);
}
}
@Override
public void onFailure(Call<Authentication> call, Throwable t) {
}
});
}
下面是我如何调用此函数并使用它来调用 API
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
service = ApiClient.getClientStats().create(ApiInterface.class);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx.getApplicationContext());
String retrievedToken = preferences.getString("token",null);
long token_expiry_time=preferences.getLong("token_expiry_time",0);
if(retrievedToken==null || token_expiry_time==0 || token_expiry_time<=Instant.now().toEpochMilli()) {
getToken();
retrievedToken=token;
}
else {
Call<Stat> call = service.getMapData("Bearer " + retrievedToken);
call.enqueue(new Callback<Stat>() {
@Override
public void onResponse(Call<Stat> call, Response<Stat> response) {
}
}
@Override
public void onFailure(Call<Stat> call, Throwable t) {
}
});
}
当您调用 getToken() 时,改装会在另一个线程上运行它。发生这种情况时,主线程继续在 if 语句中执行,并将 null 分配给 retrieveToken,因为当时令牌为 null,这就是您拥有第一个 null 的原因。然后 retrofit 完成它 exec 并设置共享首选项。在进行其他查询之前,您可以使用 LiveData 观察结果。