Изменение ориентации экрана в ручном режиме при запуске 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.

Ответ 3

У меня уже появился подобный вопрос здесь.

В основном существует пример о том, как приостановить/возобновить AsynTask при вращении устройства. Однако он по-прежнему не подходит для всех случаев (иногда невозможно безопасно приостановить действие, например, создание нового пользователя на удаленном сервере). Для этих "небезопасных" случаев вам нужно закодировать несколько, я бы назвал сложную "структуру". Вы увидите, что CommonsWare дает ссылки на github.