Android ждет завершения AsyncTask - PullRequest
37 голосов
/ 03 апреля 2012

У меня есть функция, 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's async task
                intent = new Intent(this, OrdineCreaActivity.class);
                this.startActivityForResult(intent, R.id.buttonPagamenti);
            }
            break;
...

Внутри AppHelper.isOnline() я выполняю AsyncTask, который входит в систему, делая таким образом сетевой запрос, который не может быть выполнен в пользовательском интерфейсе, потому что в противном случае я получаю исключение. Мне нужно дождаться его завершения, прежде чем возобновить с кодом внутри if. Как я могу это сделать?

Проблема в том, что действие начинается сначала, затем выполняется AsyncTask, поэтому, когда действие ожидает действительный зарегистрированный сеанс, оно прерывается.

Ответы [ 4 ]

81 голосов
/ 03 апреля 2012

У вас есть два варианта:

Либо используйте метод AsyncTask get(long timeout, TimeUnit unit), например:

task.get(1000, TimeUnit.MILLISECONDS);

Это заставит ваш основной поток ждать результата AsyncTask не более 1000 миллисекунд (согласно комментарию @ user1028741: на самом деле существует также метод бесконечного ожидания - AsyncTask#get(), который также может сделать работа для вас в некоторых случаях).

В качестве альтернативы вы можете отобразить диалоговое окно хода выполнения в асинхронной задаче до ее завершения. Смотрите эту ветку (мне не нужно копировать код). Как правило, диалоговое окно хода выполнения отображается во время выполнения асинхронной задачи и скрывается при ее завершении.

У вас есть даже третий вариант: «если Thread достаточно для ваших нужд, вы можете просто использовать его метод join. Однако, если задача занимает много времени, вам все равно придется показывать диалог прогресса, в противном случае вы получите исключение из-за того, что основной поток слишком долго неактивен.

3 голосов
/ 03 апреля 2012

попробуйте использовать

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

1 голос
/ 07 июля 2013

Ответ Рафика у меня не сработал - приложение зависло. Я думаю, что причина связана с природой isCancelled (): «Возвращает true, если эта задача была отменена до ее нормального завершения». Если задача завершается нормально (то есть не отменяется), то while(!task.isCancelled()) { } будет зацикливаться вечно.

Чтобы решить эту проблему, создайте логический флаг, который вы устанавливаете на false, а затем переключите на true в task.onPostExecute(). Затем выполните while(!flag) { } перед переключением Активности. Кроме того, если вы хотите дать основному потоку «перерыв», чтобы AsyncTask работал немного быстрее, вы можете попробовать это:

while (!flag) {
    try { Thread.sleep(100); }
    catch (InterruptedException e) { e.printStackTrace(); }
}

Мне кажется, это хорошо работает.

1 голос
/ 03 апреля 2012
intent = new Intent(this, OrdineCreaActivity.class);
context.startActivityForResult(intent, R.id.buttonPagamenti);

Напишите вышеупомянутые строки в onPostExecute () вашего AysncTask. Потому что, если мы используем AsyncTask, он не будет ждать завершения задачи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...