2012-01-24 7 views
5

работает на моем AsyncTask Интересно, почему я должен использовать onPostExecute()» AsyncTask.onPostExecute() параметр s, когда я могу просто использовать переменный экземпляр класса уровня в моем классе AsyncTask для обмена данных между doInBackground() и onPostExecute().«параметры ы против экземпляра переменных

Оба работают, но есть ли какие-либо про и con для каждого подхода?

Редактировать: когда я говорю «переменная экземпляра», я говорю о переменной частного экземпляра в расширенном классе AsyncTask. Когда класс умирает, переменная экземпляра тоже умирает.

+1

Я предполагаю, что он полезен, если ваш AsyncTask написан в отдельном файле класса – waqaslam

+0

Это не главное, потому что я думаю, что Jop van Raaij означал уровень класса самой AsyncTask –

ответ

5

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

Это будет также устранить проблемы синхронизации, так как @nico_ekito упоминалось

+1

Я согласен с @ a.ch. И это также лучше для безопасности потока. –

+0

Я думаю, что этот ответ действительно. Однако .. Только «AsyncTask» будет иметь ссылку на переменную экземпляра. Я не вижу, как происходит утечка памяти. Поскольку 'doInBackground()' и 'OnPostExecute()' называются синхронно, не очень вероятно, что JVM все еще работает над переменной экземпляра при вызове 'OnPostExcetute()' (если это даже возможно). –

0

А также размещены другие причины; если вы получите исключение в doInBackground(), вы можете просто передать параметр, представляющий ошибку, на ваш onPostExecute() и отменить любую дополнительную работу, вместо того, чтобы получить другое исключение, если поймете, что все ваши переменные не были созданы должным образом.

+0

Я бы предположил, что вы должны использовать 'cancel (boolean)'. Это также пропустит 'onPostExecute()'. Если вы хотите работать с условием состояния, связанного с материалом, который вы делаете в 'doInBackgroud()', вы должны указать состояние в параметрах (уродливо использовать один и тот же параметр для двух типов информации) или задать переменную экземпляра как 'mSuccess' (это решение я видел в некоторых учебниках). –

1

Я обнаружил, что использование переменных экземпляра в AsyncTask не является потокобезопасным. В моем случае, если я поймал и Exception в doInBackground(), я бы установил его в свою переменную экземпляра AsyncTask Exception. Тогда я бы проверить, была ли переменная нулевой или нет в onPostExecute() (я не отменю(), потому что я могу отображать сообщение в исключении для пользователя).

Во всяком случае, время от времени я записывал, что поймал исключение в doInBackground, но в onPostExecute переменная экземпляра будет равна нулю. В документации говорится, что методы называются синхронно, поэтому я не могу объяснить, почему это происходит, но я видел, как это происходит несколько раз.

Наконец, я изменил свой класс «Результат», чтобы содержать как исключение, так и исходный результат, который я хотел передать в onPostExecute. Это работает отлично.

0

Позвольте мне не согласиться с принятым ответом (и другими).

Существует абсолютно никаких проблем с безопасностью потоков при использовании полей экземпляра в AsyncTask для передачи значений от одного обратного вызова к другому. Обычно это означает прохождение значений от doInBackground() до onPostExecute(). Обратные вызовы в AsyncTask гарантируют, что никогда не будут выполняться одновременно, поэтому нет условий гонки, также нет способа потерять поле экземпляра или null, если оно было установлено в ранее выполненном обратном вызове. Теперь ответ.

Плюсы onPostExecute() параметра:

  • Параметр приходит от возвращаемого значения doInBackground(), который гарантирует, что doInBackground() должен обеспечивать значение при возврате, гарантируя, что это никогда не забывается
  • параметр является четко установлены отношения между doInBackground() и обратными вызовами, которые следуют: onPostExecute() и onCancelled(), поле экземпляра может обслуживать несколько возможных целей.

Против onPostExecute() параметра:

  • Это единственный параметр, таким образом, вы не можете передать два или несколько значений, в качестве временного решения можно обернуть несколько значений в классе вашего творчества или, возможно, Pair

Плюсы и минусы использования поля экземпляра для передачи значений от doInBackground() до onPostExecute() являются в основном точным обратным вышесказанному.

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