Лучший способ дождаться, когда retrofit2 закончит, прежде чем продолжить асинхронное

Я понимаю, что подобные вопросы были заданы, но я новичок в android и считаю ответы немного запутанными, так как они находятся в несколько другом контексте.

Я просмотрел CountDownLatch, а также использовал Threads и не знаю, какой метод использовать. Любая помощь приветствуется. Я также попытался использовать apply () вместо commit () для SharedPreferences.

Я делаю 2 вызова retrofit2 из LoginActivity. Мне нужен токен от первого вызова для использования во втором вызове. Я сохраняю токен в строке в sharedpreferences в методе onResponse первого вызова для переоснащения.

В моем втором вызове значение serverToken возвращается как токен, установленный в предыдущем запуске приложения

1-й вызов (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")); } 

Метод onResponse() – это интерфейс обратного вызова, который, просто поместив его, означает, что вы получаете информацию обратно из вашего запроса \ event (вы вызвали, он вернулся, следовательно, обратный вызов) и реализовали то, что вы хотите с ним сделать (Это интерфейс, вы его реализуете, следовательно, аннотация @Override).

это означает:

  1. Вам не нужно CountDownLatch , по крайней мере, не в этом случае, и Retrofit2 позаботится о потоковой передаче для вас.

  2. Нет реальной потребности в SharedPreferences , вы можете просто вызвать метод, который вы хотите прямо из этого обратного вызова, поскольку информация находится в этом экземпляре (если вы не хотите сохранять его по причинам, отличным от следующего запроса, см. Следующий …).

  3. Если вы хотите локально сохранить значение, потому что оно вам понадобится позже (или позже использовать в качестве автозапуска, вы можете использовать SharedPreferences , но вам не нужно получать оттуда значение в этом экземпляре – поскольку оно существует в Экземпляр обратного вызова (вы сохраняете значение прямо там, оно избыточно, чтобы загрузить его из Prefs снова, в то время как ответ содержит точное значение, которое можно просто передать.

так:

 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! } 

Ну, я нашел решение. Найден ответ на модифицированный github
«Использовать обратный вызов из метода 1 для запуска метода 2»
Я переместил 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"); } } } 

Не стесняйтесь удалять свой вопрос. Я оставлю это, поскольку это может помочь кому-то другому

Вы можете вызвать connectToPush(); Из части onResponse вашего запроса на onResponse .

Intereting Posts
Где хранить конфиденциальную глобальную информацию, такую ​​как ключи API в приложении Android? ACRA: настроен для отправки отчета по почте, но не получает никакой почты Как избежать загрузки данных кэшированных приложений с Google Диска Какие телефоны Android имеют большие размеры экрана OnConfigurationChanged не вызывается в mono android GetView Vs. BindView в пользовательском CursorAdapter? OOD и Передача активности в качестве параметра для конструкторов других классов Eclipse, Android: Неожиданно Невозможно выполнить dex: несколько файлов dex определяют Log.d и влияние на производительность Проблема спаривания с низкой энергией Bluetooth (BLE) Moto G NetBeans с NBAndroid – не может найти символ setContentView (R.layout.main); Google добавляет API только 5 результатов Android EditText / TextView, как заставить каждое слово начинаться с верхнего регистра, а все остальные символы слов – строчными буквами Обновлять ОС Android программно Html.fromHtml (текст) не работает