Android ждет AsyncTask, чтобы закончить
У меня есть функция AppHelper.isOnline(Context context)
, я вызываю в разных частях моего приложения, чтобы проверить, что сеанс не был тайм-аутом, прежде чем делать HTTP-запрос.
public void onClick(View v) {
Intent intent = null;
switch (v.getId()) {
case R.id.buttonPagamenti:
if (AppHelper.isOnline(this))
{
//here AppHelper.isOnline should have finished it async task
intent = new Intent(this, OrdineCreaActivity.class);
this.startActivityForResult(intent, R.id.buttonPagamenti);
}
break;
...
Внутри AppHelper.isOnline()
, я запускаю AsyncTask
, который входит в систему, что делает сетевой запрос, который не может быть запущен в пользовательском интерфейсе, потому что в противном случае я получаю исключение. Мне нужно дождаться, когда он закончит ПЕРЕД продолжением кода внутри if. Как я могу это сделать?
Проблема заключается в том, что действие запускается первыми, затем выполняется AsyncTask
, поэтому, когда активность ожидает действительного сеанса входа в систему, он прерывается.
Ответы
Ответ 1
У вас есть два варианта:
Используйте метод AsyncTask
get(long timeout, TimeUnit unit)
следующим образом:
task.get(1000, TimeUnit.MILLISECONDS);
Это приведет к тому, что ваш основной поток будет ждать результата AsyncTask
не более 1000 миллисекунд (согласно комментарию @user1028741: на самом деле существует также бесконечно ожидающий метод - AsyncTask#get()
, который также может работать для вас в некоторых случаях).
В качестве альтернативы вы можете отобразить диалог выполнения в задаче async до тех пор, пока она не закончится. Смотрите этот поток (мне не нужно копировать код). В основном отображается диалоговое окно прогресса во время выполнения задачи async и скрывается при завершении.
У вас есть даже третий вариант: "Если Thread
достаточно для ваших нужд, вы можете просто использовать его метод join
. Однако если задача занимает много времени, вам все равно нужно будет отобразить диалог прогресса, иначе вы получите исключение из-за того, что основной поток неактивен слишком долго.
Ответ 2
попробуйте использовать
if (AppHelper.isOnline(this))
{
while(!task.isCancelled()){
// waiting until finished protected String[] doInBackground(Void... params)
}
intent = new Intent(this, OrdineCreaActivity.class);
this.startActivityForResult(intent, R.id.buttonPagamenti);
}
Для получения дополнительной информации прочитайте http://developer.android.com/reference/android/os/AsyncTask.html
Ответ 3
intent = new Intent(this, OrdineCreaActivity.class);
context.startActivityForResult(intent, R.id.buttonPagamenti);
Напишите вышеприведенные строки в onPostExecute() из AysncTask. Потому что, если мы используем AsyncTask, он не будет ждать там до завершения задачи.
Ответ 4
Ответ Rafiq не работал у меня - приложение висело. Я думаю, что причина связана с природой isCancelled(): "Возвращает true, если эта задача была отменена, прежде чем она завершится нормально". Если задача завершается нормально (т.е. Не отменяется), то while(!task.isCancelled()) { }
будет циклически навечно.
Чтобы решить эту проблему, создайте логический флаг, который вы установите в false
, а затем переверните на true
в task.onPostExecute()
. Затем выполните while(!flag) { }
, прежде чем переключать действия. Кроме того, если вы хотите дать основному потоку "перерыв", чтобы процесс AsyncTask немного ускорился, вы можете попробовать:
while (!flag) {
try { Thread.sleep(100); }
catch (InterruptedException e) { e.printStackTrace(); }
}
Кажется, он работает хорошо для меня.