Mejor manera de esperar a que retrofit2 termine antes de continuar async

Me doy cuenta de preguntas similares se han hecho, pero soy nuevo en android y encontrar las respuestas un poco confuso ya que se encuentran en un contexto ligeramente diferente.

He mirado en CountDownLatch aswell como el uso de hilos y no estoy seguro de qué método utilizar. Cualquier ayuda sería muy apreciada. También he intentado usar apply () en lugar de commit () para SharedPreferences.

Estoy haciendo 2 llamadas retrofit2 desde LoginActivity. Necesito el token de la primera llamada para usar en la segunda llamada. Estoy guardando el token en una cadena en sharedferencias en el método onResponse de la primera llamada retrofit.

En mi segunda llamada el valor de serverToken volverá como el token establecido en la ejecución anterior de la aplicación

Primera llamada (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(); } 

Mi segunda llamada de Retrofit

 public void connectToPush(){ Log.i("sharedpreferencesToken", LoginActivity.preferences.getString("serverToken", "null serverToken")); } 

El método onResponse() es una interfaz de devolución de llamada que, simplemente poniéndola, significa que es donde se obtiene la información de su solicitud \ evento (llamó, regresó, por lo tanto, callback) e implementar lo que desea hacer con él (Es una interfaz, se implementa, por lo tanto, la anotación @Override).

esto significa:

  1. Usted no necesita CountDownLatch , al menos no en este caso, y Retrofit2 se encarga del enhebrado para usted.

  2. No hay necesidad real de SharedPreferences , sólo puede llamar al método que desea directamente de esa devolución de llamada, ya que la información es en esa instancia (a menos que desee guardarlo por razones distintas a la siguiente solicitud, consulte siguiente …).

  3. Si desea almacenar localmente el valor porque lo necesita más tarde (o para usarlo como una cosa de inicio de sesión automático más tarde, puede utilizar SharedPreferences , pero no necesita obtener su valor desde allí en esa instancia, ya que existe en La instancia de devolución de llamada (guardando el valor allí mismo, es redundante cargarlo desde el Prefs de nuevo mientras la respuesta contiene el valor exacto que se puede pasar simplemente.

asi que:

 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"); } } } 

Y en su segunda llamada:

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

Bueno, terminé encontrando la solución. Encontrado la respuesta en el github retrofit
"Utilice la devolución de llamada del método 1 para activar el método 2"
Moví connectToPush () a la onResponse de la primera llamada.

  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"); } } } 

Siéntase libre de borrar mi pregunta. Lo dejaré como puede ayudar a otra persona

Puede llamar a connectToPush(); Desde la parte onResponse de su llamada de Retrofit.

  • ¿Cómo puedo cambiar la tasa o el período de una tarea repetida mediante ScheduledExecutorService?
  • ¿Cómo poner un runnable en paquete?
  • Actualizar la interfaz de usuario de Android desde un subproceso de otra clase
  • Android: obtenga tiempo hasta que Runnable se ejecute a través de Handler
  • Actualización de la interfaz de usuario desde un servicio (mediante un controlador?)
  • ¿Un runnable en un servicio se ejecuta en el subproceso de interfaz de usuario
  • Cómo implementar un Runnable con un no-bloqueador Looper / Handler
  • Tomando un cómputo pesado del subproceso de la interfaz de usuario de Android
  • Cómo pasar o asignar un valor obtenido en un runOnUiThread
  • ¿Es este hilo seguro?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.