Задача Android ASync ProgressDialog не отображается, пока не завершится фоновый поток - PullRequest
15 голосов
/ 24 апреля 2010

У меня есть операция Android, которая захватывает RSS-канал с URL-адреса и использует SAX-анализатор для вставки каждого элемента из XML в массив. Это все работает нормально, но, как и ожидалось, занимает немного времени, поэтому я хочу использовать AsyncActivity, чтобы сделать это в фоновом режиме. Мой код выглядит следующим образом:

class AddTask extends AsyncTask<Void, Item, Void> {

    protected void onPreExecute() {
        pDialog = ProgressDialog.show(MyActivity.this,"Please wait...", "Retrieving data ...", true);
    }

    protected Void doInBackground(Void... unused) {
        items = parser.getItems();

        for (Item it : items) {
            publishProgress(it);
        }
        return(null);
    }

    protected void onProgressUpdate(Item... item) {
        adapter.add(item[0]);
    }

    protected void onPostExecute(Void unused) {
        pDialog.dismiss();
    }
  }

Который я называю onCreate() с

new AddTask().execute();

Строка items = parser.getItems() работает нормально - items является массивом, содержащим каждый элемент из XML. Проблема, с которой я сталкиваюсь, заключается в том, что при запуске операции ProgressDialog, который я создаю в onPreExecute(), не отображается до тех пор, пока после не завершится метод doInBackground(). я получаю черный экран, длинную паузу, затем полностью заполненный список с элементами. Почему это происходит? Почему не рисуется пользовательский интерфейс, отображается ProgressDialog, парсер получает элементы и постепенно добавляет их в список, а затем ProgressDialog закрывает?

Ответы [ 4 ]

13 голосов
/ 17 ноября 2010

Я подозреваю, что что-то блокирует ваш поток пользовательского интерфейса после выполнения задачи. Например, я видел, как люди делают такие вещи:

MyTask myTask = new MyTask();
TaskParams params = new TaskParams();
myTask.execute(params);
myTask.get(5000, TimeUnit.MILLISECONDS);

Вызов get в данном случае блокирует поток пользовательского интерфейса (который, по-видимому, приводит к выполнению задачи здесь ...), что предотвратит любые связанные с пользовательским интерфейсом вещи в методе onPreExecute () вашей задачи до тех пор, пока задача фактически не завершится. Упс! Надеюсь это поможет.

11 голосов
/ 25 апреля 2010

Это работает для меня

@Override
protected void onPreExecute() {
        dialog = new ProgressDialog(viewContacts.this);
        dialog.setMessage(getString(R.string.please_wait_while_loading));
        dialog.setIndeterminate(true);
        dialog.setCancelable(false);
        dialog.show();
    }
4 голосов
/ 18 ноября 2013

Это потому, что вы использовали AsyncTask.get(), который блокирует поток пользовательского интерфейса: «При необходимости ожидает завершения вычислений, а затем получает его результат».1004 * Создайте экземпляр AsyncTask и завершите все, что вы хотите сделать в AsyncTask.onPostExecution().

1 голос
/ 17 июня 2011

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

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

Таким образом, ваш поток пользовательского интерфейса не будет заблокирован, как указано выше. Вы должны позаботиться о любом последующем использовании результата за пределами подкласса, так как фоновый поток все еще может работать и ваш член не будет иметь нового значения.

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