2011-08-10 3 views
0

AsyncTask выполняется по щелчку:параллельное выполнение AsyncTask

List<RSSItem> list = new Vector<RSSItem>(); 
private OnClickListener click = new OnClickListener() { 
    public void onClick(View view) { 
     list.clear(); 
     if((dft.getStatus().toString()).equals("RUNNING")) dft.cancel(true); 
     currentCategory = catigoriesHolder.indexOfChild(view); 
     dft = new DownloadFilesTask(); 
     dft.execute(rssFeedURL[currentCategory]); 
    } 
}; 

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

Вопрос касается версии 1.6.

+0

См. Этот вопрос: http://stackoverflow.com/questions/9893813/can-an-android-asynctask-doinbackground-be-synchronized-to-serialize-the-task-ex –

ответ

3

Прежде всего async task в целом не запускается в тот же момент, но выполнение одной и той же задачи async на самом деле является очередью. так представьте себе, если вы создаете 2 экземпляра вашего DownloadFilesTask и выполнять их в том же методе, как:

task1.execute(); 
task2.execute(); 

это означает, что задача 2 не будет работать, пока task1 не закончат весь onPreExecute, DoInBg, процесс onPostExecute так что вы можете будьте уверены, что это не произойдет одновременно. также taskStatus - это ENUM. Вы можете проверить это, как, например, не в виде строки, как:

task.getStatus()==Status.FINISHED 

в вашем случае, если вы не хотите стоять в очереди несколько задач до тех пор, в настоящее время работает один не будет завершена, то сделать что-то вроде этого:

if(task==null || task.getStatus()!=Status.FINISHED){ 
    task = new DownloadFilesTask(); 
    task.execute(); 
} 

Отмена задачи означает, что doInBackground будет работать, но postExecute не будет. вы можете проверить, есть ли задание isRunning, чтобы отменить его также при обработке bg.

+1

Это фактически не документировано. На Android 1.5 все задачи async были поставлены в очередь, на Android 1.6+ несколько «AsyncTask's» могли работать параллельно. Планируется восстановление «последовательного» исполнения «AsyncTask's» в последующих выпусках Android. Но поскольку это еще не задокументировано, никто не должен полагаться на это поведение. (Http://groups.google.com/group/android-developers/msg/3deeb36dccb4e9a5) – inazaruk

+0

Должен ли я понять, что то, как я это делаю, неверно, и это вызовет ошибку. Я понял, что ты имеешь в виду, и полностью понял это! Но это будет заблокировано, если я нажму на новую категорию, я имею в виду, что я нажимаю на другую ссылку (кнопка), и ничего не происходит, пока текущий экземпляр ** задачи ** не будет завершен. Он защищен, но если соединение с пользователем происходит медленно, для его завершения потребуется несколько секунд. Есть ли другой способ прервать текущую задачу, иначе я буду реализовывать этот путь и считаю ваш ответ правильным? – nenito

+0

Ну, единственный способ проверить статус во время асинхронной задачи. вы можете использовать Threads. Они запускаются параллельно, они немного тяжелее, но все равно будут выполнять требуемую работу. также есть проект CommonsWare, который позволяет одновременно запускать несколько задач. Найдите AsyncTaskEx: http://code.google.com/p/alldroid/source/browse/trunk/AllDroid/src/com/commonsware/cwac/task/AsyncTaskEx.java?spec=svn24&r=24 – DArkO

2

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

List<RSSItem> list = new Vector<RSSItem>(); 
DownloadFilesTask downloadTask = null; 

private OnClickListener click = new OnClickListener() { 
    public void onClick(View view) { 
     list.clear(); 
     if((dft.getStatus().toString()).equals("RUNNING")) dft.cancel(true); 
     currentCategory = catigoriesHolder.indexOfChild(view); 

     if(downloadTask == null){ 
      downloadTask = new DownloadFilesTask(); 
      downloadTask.execute(rssFeedURL[currentCategory]); 
     } else { 
      //show warning here 
     } 
    } 
} 

Конечно, вам нужно установить downloadTask в null в onPostExecute() для этой работы.


В качестве дополнительного преимущества теперь вы можете отменить выдающуюся задачу, если активность уничтожается:

@Override 
onDestroy() { 
    if(downloadTask != null) { 
     downloadTask.cancel(); 
    } 
} 

Что вы должны делать в любом случае.

+0

Он хранится как член, Я просто не разделял эту часть источника. Нулевая проверка также выполняется. Спасибо за '@Override onDestroy()' это действительно полезно. – nenito

Смежные вопросы