Как заставить AsyncTask отменить себя, когда действие завершится


Я разрабатываю ListActivity, в котором множество информации отображается в каждом элементе списка.
С момента сбора данных для отображения в каждой записи списка (эскиз с SD-карты и подсчет из БД) требует много времени. Я подумал об использовании AsyncTasks, чтобы освободить основной поток от нагрузки и позволить пользователю быстро прокручивать список без задержек.

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

public void bindView(View view, Context context, Cursor cursor) {
    [...]
    MyAsyncTask t (MyAsyncTask) myImageView.getTag();
    if (t != null) {
        t.cancel(true);
        t = null;
    }
    t = new MyAsyncTask();
    myImageView.setTag(t);
    t.execute();
    [...]
}

Эта часть должна работать, но моя проблема в том, что когда действие заканчивается или пользователь меняет ориентацию. Я бы предпочел избегать хранения массива или хэш-карты моих AsyncTasks, просто чтобы иметь возможность отменить их все в onPause или onStop.
Из чтения, которое я сделал в Интернете, AsyncTasks продолжит работать в фоновом режиме после изменения ориентации или действие завершается, и, что еще хуже, оно будет поддерживать активность, предотвращая сборку мусора (что определенно не то, что я хочу).

Любые идеи или предложения о том, как я могу это сделать?
Должен ли я использовать что-то еще, кроме AsyncTasks?


person Francois Dermu    schedule 18.03.2011    source источник
comment
Ведение списка всех ваших задач может решить эту проблему, почему вам не нравится такой подход?   -  person ernazm    schedule 18.03.2011
comment
Просто кажется, что должно быть лучшее решение.   -  person Francois Dermu    schedule 18.03.2011
comment
То, что я имел в виду (и описанное в моем вопросе, на самом деле не имеет ожидаемого эффекта, поскольку задачи не останавливаются, когда я вызываю cancel(true), и я получаю java.util.concurrent.RejectedExecutionException в строке, где я пытаюсь execute() выполнить следующую задачу после игры со списком и после того, как пул потоков для AsyncTasks заполнится. Я знаю, что идея состоит в том, чтобы периодически проверять isCancelled() с doInBackground(Object[]), чтобы завершить задачу как можно раньше, но в моем случае это невозможно, так как я просто вызываю одну функцию и не нет доступа к его источнику.: /   -  person Francois Dermu    schedule 19.03.2011


Ответы (1)


Я бы подумал о замене массива AsyncTasks одним AsyncTask. Здесь может помочь onProgressUpdate.

person ernazm    schedule 18.03.2011
comment
Вы предлагаете, чтобы я загружал свои элементы только по одному, вместо того, чтобы загружать их все по мере их появления? Я не уверен, что понимаю ваш ответ. - person Francois Dermu; 18.03.2011