Изменение ориентации экрана в ручном режиме при запуске AsyncTasks
Я некоторое время искал это. Как правильно обрабатывать изменения ориентации экрана, когда у меня есть отдельный запуск Thread
/AsyncTask
? В настоящее время у меня есть
android:configChanges="orientation|keyboard|keyboardHidden"
в моем AndroidManifest.xml
, но это не рекомендуется:
Примечание.. Использовать этот атрибут следует избегать и использовать только как последний. Пожалуйста, прочитайте "Обработка изменений времени выполнения" для получения дополнительной информации о том, как правильно обрабатывать перезапуск из-за изменения конфигурации.
Кроме того, в эмуляторе 2.3 он работает при переключении на landscape
, но сбой на portrait
завершается с ошибкой.
Теперь причина, по которой я использую configChanges
, заключается в том, что когда пользователь переключает ориентацию, я могу запустить AsyncTask
, сделать некоторый сетевой трафик, и я не хочу, чтобы он остановился.
Есть ли другой способ сделать это, или есть способ исправления 2.3, чтобы вернуться к портрету?
Я знаю о onRetainNonConfigurationInstance
, но я не уверен, что было бы неплохо "сохранить" экземпляр AsyncTask
, главным образом потому, что класс, который расширяет AsyncTask
, не является статическим (поэтому он привязан к Activity
) - и это должно быть, потому что в onPostExecute()
он вызывает методы из экземпляра Activity
.
Ответы
Ответ 1
У меня была аналогичная проблема с вашим и работала вокруг него, реализовав AsyncTask
как часть класса, который наследует от Application
класс. Класс Application
доступен весь срок службы приложения. Поэтому вам не нужно беспокоиться о том, что ваш AsyncTask
будет прерван, если не будет уничтожено все приложение.
Чтобы получить уведомление, когда задача завершилась, Activity
должен реализовать интерфейс, который он использует, чтобы зарегистрировать себя в классе Application
.
Когда ваше приложение уничтожается из-за поворота экрана, вы можете отменить регистрацию Activity
из класса Application
и перерегистрировать ее при ее воссоздании. Если задача заканчивается между уничтожением и реставрации, результат операции может быть сохранен в классе Application
, тем временем, чтобы Activity
мог проверить, все еще запущена задача или результат уже доступен, когда он воссоздан.
Еще одно преимущество заключается в том, что у вас есть прямой доступ к контексту приложений, потому что класс Application
является подклассом класса Context
.
Ответ 2
Посмотрите библиотеку droid-fu BetterAsyncTask
. Он предназначен для обработки этого точного случая.
http://brainflush.wordpress.com/2009/11/16/introducing-droid-fu-for-android-betteractivity-betterservice-and-betterasynctask/
Ответ 3
У меня уже появился подобный вопрос здесь.
В основном существует пример о том, как приостановить/возобновить AsynTask
при вращении устройства. Однако он по-прежнему не подходит для всех случаев (иногда невозможно безопасно приостановить действие, например, создание нового пользователя на удаленном сервере). Для этих "небезопасных" случаев вам нужно закодировать несколько, я бы назвал сложную "структуру". Вы увидите, что CommonsWare дает ссылки на github.