条件下改造异步调用

Retrofit Asynchronous call on condition

我必须从 API 接收令牌,将其存储在共享首选项中并仅在 如果 令牌具有时调用 API已到期。令牌在 200000 秒后过期。 基本上我会尝试按照这些说明进行操作:

  1. 生成令牌并将其存储在会话中
  2. 存储您生成令牌的时间a.k.a当前时间
  3. 每当您进行 API 调用时,根据当前时间检查令牌过期时间
  4. 如果令牌过期时间大于当前时间,则重新验证并在后台生成新令牌

然而,第一次 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 观察结果。