Работа с моей AsyncTask
Интересно, почему я должен использовать параметр onPostExecute()
, когда я могу просто использовать переменную AsyncTask
класса в классе AsyncTask
для обмена данными между doInBackground()
и onPostExecute()
.
Оба работают, но есть ли какие-либо pro и con для каждого подхода?
Изменить: когда я говорю «переменная экземпляра», я говорю о переменной частного экземпляра в расширенном классе AsyncTask
. Когда класс умирает, переменная экземпляра тоже умирает.
Это может уменьшить вероятность утечки памяти, так как вы не держите ссылку на свой объект на уровне класса, а только те методы AsyncTask.
Это также устранит проблемы синхронизации, как отметил @nico_ekito
Я обнаружил, что использование переменных экземпляра в AsyncTask не является потокобезопасным. В моем случае, если я поймал и Exception в doInBackground (), я бы установил его в свою переменную экземпляра AsyncTask Exception. Тогда я бы проверить, была ли переменная нулевой или нет в onPostExecute () (я не отменю (), потому что я могу отображать сообщение в исключении для пользователя).
Во всяком случае, время от времени я записывал, что я поймал исключение в doInBackground, но в onPostExecute переменная экземпляра будет равна нулю. В документации говорится, что методы называются синхронно, поэтому я не могу объяснить, почему это происходит, но я видел, как это происходит несколько раз.
Наконец, я изменил свой класс «Результат», чтобы содержать как исключение, так и исходный результат, который я хотел передать в onPostExecute. Это работает отлично.
Как и другие опубликованные причины; Если вы получаете исключение в doInBackground()
, вы можете просто передать параметр, представляющий ошибку для вашего onPostExecute()
и отменить любую дополнительную работу, вместо того, чтобы получать другое исключение, когда понимаете, что все ваши переменные не были созданы должным образом ,
Позвольте мне не согласиться с принятым ответом (и другими).
Существует абсолютно никаких проблем с безопасностью потоков, связанных с использованием полей экземпляра в AsyncTask для передачи значений из одного обратного вызова в другой. Обычно это означает передачу значений из doInBackground()
в onPostExecute()
. Обратные вызовы в AsyncTask гарантированно никогда не выполняются одновременно, поэтому нет условий гонки, также нет способа потерять поле экземпляра или null, если оно было установлено в ранее выполненном обратном вызове. Теперь ответ.
Плюсы параметра onPostExecute()
:
doInBackground()
который гарантирует, что doInBackground()
должен предоставить значение при возврате, гарантируя, что он никогда не будет забыт doInBackground()
и обратными вызовами, которые следуют: onPostExecute()
и onCancelled()
, поле экземпляра может служить нескольким возможным целям onPostExecute()
параметра onPostExecute()
:
Pair
Плюсы и минусы использования поля экземпляра для передачи значений из doInBackground()
в onPostExecute()
в основном являются точными обратными выше.