Я конвертирую свой код из использования Handler
в AsyncTask
. Последний хорош в том, что делает - асинхронные обновления и обработка результатов в основном потоке пользовательского интерфейса. Что мне неясно, так это то, как обрабатывать исключения, если что-то пошло не так AsyncTask#doInBackground
.
Для этого я должен иметь обработчик ошибок и отправлять ему сообщения. Это работает нормально, но это "правильный" подход или есть лучшая альтернатива?
Также я понимаю, что если я определяю обработчик ошибок как поле Activity, он должен выполняться в потоке пользовательского интерфейса. Однако иногда (очень непредсказуемо) я получаю исключение, говорящее о том, что код, запущенный из Handler#handleMessage
, выполняется в неправильном потоке. Должен ли я Activity#onCreate
вместо этого инициализировать обработчик ошибок ? Размещение runOnUiThread
в Handler#handleMessage
кажется избыточным, но это выполняется очень надежно.
Ответы:
Я держусь за
Throwable
илиException
в самомAsyncTask
экземпляре, а затем что-то с ним делаюonPostExecute()
, поэтому моя обработка ошибок имеет возможность отображать диалоговое окно на экране.источник
AsyncTask
следующую схему, которую я описываю.Создайте объект AsyncResult (который вы также можете использовать в других проектах)
Верните этот объект из ваших методов AsyncTask doInBackground и проверьте его в postExecute. (Вы можете использовать этот класс в качестве базового класса для других ваших асинхронных задач)
Ниже приведен макет задачи, которая получает ответ JSON от веб-сервера.
источник
super()
в ,AsyncTaskResult
когда класс ничего не распространяется?Когда я чувствую необходимость правильно обрабатывать исключения
AsyncTask
, я использую это как суперкласс:Как обычно, вы переопределяете
doInBackground
в своем подклассе для выполнения фоновой работы, к счастью выбрасывая исключения, где это необходимо. Затем вы вынуждены реализоватьonPostExecute
(потому что это абстрактный), и это мягко напоминает вам обрабатывать все типыException
, которые передаются в качестве параметра. В большинстве случаев исключения приводят к некоторому типу пользовательского интерфейса, поэтомуonPostExecute
это идеальное место для этого.источник
params
форвард, чтобы он больше походил на оригинал и его было легче перенести?new Task("Param").execute()
болееnew Task().execute("Param")
.Если вы хотите использовать платформу RoboGuice, которая дает вам другие преимущества, вы можете попробовать RoboAsyncTask, который имеет дополнительный Callback onException (). Работает очень хорошо, и я им пользуюсь. http://code.google.com/p/roboguice/wiki/RoboAsyncTask
источник
RoboGuice
еще жив? Кажется, не обновляется с 2012 года?Я создал собственный подкласс AsyncTask с интерфейсом, который определяет обратные вызовы для успеха и неудачи. Поэтому, если в AsyncTask выдается исключение, функция onFailure получает исключение, в противном случае обратный вызов onSuccess получает ваш результат. Почему у андроида нет чего-то лучшего, я не знаю.
источник
Более полное решение для решения Cagatay Kalan показано ниже:
AsyncTaskResult
ExceptionHandlingAsyncTask
Пример задачи
источник
Этот простой класс может помочь вам
источник
Другой способ, который не зависит от общего доступа к переменным, заключается в использовании отмены.
Это из Android документов:
Таким образом, вы можете вызвать cancel в операторе catch и быть уверенным, что onPostExcute никогда не вызывается, а вместо этого onCancelled вызывается в потоке пользовательского интерфейса. Таким образом, вы можете показать сообщение об ошибке.
источник
cancel(boolean)
в результате вызовonCancelled()
существовал с самого начала, ноonCancelled(Result)
был добавлен в API 11 .На самом деле, AsyncTask использует FutureTask & Executor, FutureTask поддерживает цепочку исключений. Сначала давайте определим вспомогательный класс
Во-вторых, давайте использовать
источник
Лично я буду использовать этот подход. Вы можете просто перехватить исключения и распечатать трассировку стека, если вам нужна информация.
сделайте вашу задачу в фоновом режиме, верните логическое значение.
это вот так:
источник
Другой возможностью будет использование в
Object
качестве типа возвращаемого значения иonPostExecute()
проверки типа объекта. Это коротко.источник
Если вы знаете правильное исключение, вы можете позвонить
например:
и перейдите к «onProgressUpdate» и выполните следующие действия
Это будет полезно только в некоторых случаях. Также вы можете сохранить
Global
Exception
переменную и получить доступ к исключению.источник