在继续异步之前等待retrofit2完成的最佳方法

时间:2016-05-25 18:37:21

标签: android asynchronous runnable retrofit2 countdownlatch

我意识到有类似的问题已被问到,但我是android的新手并且发现答案有点令人困惑,因为它们处于稍微不同的背景中。

我查看过CountDownLatch以及使用Threads,我不确定使用哪种方法。任何帮助将非常感激。我也尝试使用apply()而不是commit()来实现SharedPreferences。

我正在从LoginActivity进行2次retrofit2调用。我需要第一次调用中的令牌才能在第二次调用中使用。我将令牌保存到第一次改装调用的onResponse方法的sharedpreferences中的字符串。

在我的第二次调用中,serverToken的值将作为在上一次运行应用程序中设置的令牌返回

第一次通话(getToken)onResponse

   call.enqueue(new retrofit2.Callback<TokenResponse>() {    

            @Override
            public void onResponse(Call<TokenResponse> call, retrofit2.Response<TokenResponse> response) {

                if (response.isSuccessful()) {
                    TokenResponse tokenResponse = response.body();

                    LoginActivity.editor.putString("serverToken", tokenResponse.getAccessToken());
                    LoginActivity.editor.commit();

                } else {
                    Log.i("Server Token", "failed");
                }
            }
 }

LoginActivity

public class LoginActivity extends AppCompatActivity {

    public static SharedPreferences preferences;
    public static SharedPreferences.Editor editor;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        authenticationController = new AuthenticationController();
        preferences = PreferenceManager.getDefaultSharedPreferences(this);
        editor = preferences.edit();
    }

    public void onLoginClicked(View view) {
        getToken();    //FIRST RETROFIT CALL
        connectToPush(); //SECOND CALL WHERE I NEED TOKEN FROM FIRST CALL
    }

    public void getToken() {
        authenticationController.login(grantType, username, password);
    }

    public void connectToPush() {
        authenticationController.connectToPush();
    }

我的第二次改造电话

public void connectToPush(){

  Log.i("sharedpreferencesToken", LoginActivity.preferences.getString("serverToken", "null serverToken"));

}

3 个答案:

答案 0 :(得分:1)

onResponse()方法是一个回调接口,简单地说就是它,这意味着你可以从你的请求\事件中获取信息(你调用它,它回来了,因此回调)并实现你的想要用它(它是一个接口,你实现它,因此@Override注释)。

这意味着:

  1. 您不需要CountDownLatch,至少在这种情况下不需要,而且Retrofit2会为您处理线程。

  2. 不需要SharedPreferences,您可以直接从该回调中调用您想要的方法,因为该信息位于该实例中(除非您因为下一个请求以外的原因而保存它) ,见下......)。

  3. 如果您想在本地存储该值,因为您以后需要它(或稍后用作自动登录的东西,您可以使用SharedPreferences,但您不需要获取你在那个实例中的值 - 因为它存在于回调实例中(你在那里保存值,在从响应中保存可以简单传递的确切值时,从Prefs再次加载它是多余的。) / p>

  4. 这样:

    call.enqueue(new retrofit2.Callback<TokenResponse>() {    
    
            @Override
            public void onResponse(Call<TokenResponse> call, retrofit2.Response<TokenResponse> response) {
    
                if (response.isSuccessful()) {
                    TokenResponse tokenResponse = response.body();
    
                    //right here you can call the other request and just give it the token
                    connectToPush(tokenResponse);
    
                    //if you really need to, save your value
                    LoginActivity.editor.putString("serverToken", tokenResponse.getAccessToken());
                    LoginActivity.editor.commit();
    
                } else {
                    Log.i("Server Token", "failed");
                }
            }
     }
    

    在你的第二个电话中:

    public void connectToPush(TokenResponse tokenFromFirstRequest){
    
     //fire the next request using your token as a param!
    
    }
    

答案 1 :(得分:0)

我最终找到了解决方案。在改造github上找到了答案 &#34;使用方法1中的回调来触发方法2&#34;
我将connectToPush()移动到第一次调用的onResponse。

  call.enqueue(new retrofit2.Callback<TokenResponse>() {    

            @Override
            public void onResponse(Call<TokenResponse> call, retrofit2.Response<TokenResponse> response) {

                if (response.isSuccessful()) {


               TokenResponse tokenResponse = response.body();

                LoginActivity.editor.putString("serverToken", tokenResponse.getAccessToken());
                LoginActivity.editor.commit();

                connectToPush(); //MOVED TO HERE

            } else {
                Log.i("Server Token", "failed");
            }
        }
 }

随意删除我的问题。我会离开它,因为它可以帮助别人

答案 2 :(得分:0)

您可以从改造通话的connectToPush();部分拨打onResponse