Подтвердить что ты не робот

Как Android обрабатывает фоновые потоки при выходе из Activity?

Мне нужно мое приложение для Android, чтобы сохранить его на диске, когда его активность будет помещена в фоновом режиме или убита. Было предложено начать поток, когда вызывается onPause() и выполняются какие-либо дорогостоящие процедуры ввода-вывода (см. Сохранение/загрузка документа быстро и надежно для редактора изображений).

В каких ситуациях ОС будет убивать поток и как обычно происходят эти ситуации?

Я предполагаю, что это будет похоже на то, как решаются действия, когда ОС может произвольно решить убить поток, но в основном будет делать это только тогда, когда ресурсы крайне ограничены. Было бы неплохо найти определенную документацию об этом, хотя.

От игры с некоторым тестовым кодом фоновый поток, запущенный в onPause(), будет работать бесконечно в фоновом режиме на моем устройстве (я пытался загружать множество приложений и не мог заставить его быть убитым).

Для моего конкретного приложения я пишу редактор растровых изображений, в котором я использую шаблон Command и шаблон Memento, чтобы разрешить отмену и повтор изменений. Я хотел бы, чтобы пользователь мог отменить/изменить свои правки, например, пользователь получает телефонный звонок, и активность убивается, когда он помещается в фоновом режиме. Лучшее решение, которое я могу придумать, - использовать фоновый поток для постоянного сохранения моих команд и объектов памяти на диске во время использования приложения и для завершения сохранения любых объектов, оставшихся в фоновом потоке, если вызывается onPause. В худшем случае, если поток убит, я только потеряю некоторые изменения.

4b9b3361

Ответ 1

В каких ситуациях ОС будет убивать поток и как обычно происходят эти ситуации?

ОС не будет убивать поток, если только это не убивает процесс. Android не делает ничего с потоками, которые вы создаете сами. Если вы являетесь процессом переднего плана, вы не будете убиты. Шансы Android, убивающие процесс в течение нескольких секунд после проигрыша переднего плана (после onPause()), незначительны. Документацию о времени жизни процесса - что есть в ней - можно найти здесь.

Ответ 2

Ваша нить может быть убита в любое время после того, как действие будет уничтожено или оно никогда не будет убито. В зависимости от такой нити очень плохая форма - вы можете закончить с полузаполненной операцией или с нитью, которая торчит навсегда.

Если вы хотите выполнить фоновый режим, который продолжается, даже если нет активности переднего плана, вы почти всегда хотите запустить его внутри Сервиса. С другой стороны, услуга с меньшей вероятностью будет убита, но нет гарантии, если вы не используете "startForeground". Это приведет к появлению уведомления пользователя о том, что что-то происходит в фоновом режиме, но насколько я знаю, это единственный способ запустить асинхронный фоновый поток, который гарантированно не будет убит.

Честно говоря, правильный ответ заключается в том, чтобы убедиться, что никогда не существует какого-либо временного состояния процесса, которое потребуется много времени для сохранения. Если вам нужно написать большой файл, чтобы отразить несколько пользовательских изменений, подумайте о том, чтобы сохранить "журнал транзакций", который вы можете использовать для создания перезапускаемой операции сохранения. Учитывая это, вы можете безопасно запускать свои сейвы в службе и знать, что даже если он будет убит, он будет автоматически перезагружен, когда ресурсы станут доступными.

Ответ 3

Как правило, сохранение состояния в onPause - это правильная вещь, если это быстро. Я не думаю, что это четко задокументировано, когда процесс убит, но иногда вы видите его в logcat, когда вы запускаете некоторые требовательные приложения (скажем, после запуска Google Earth и браузера).

В Android DevTools также есть возможность автоматически уничтожать действия при удалении от них, хотя это, вероятно, не распространяется на процесс. (DevTools находятся в эмуляторе и на некоторых корневых телефонах).

Я думаю, что ваш подход звучит разумно - используйте поток с низким приоритетом, чтобы постоянно обновлять данные сохранения и придать ему нормальный приоритет в onPause и установить флаг в onPause, который сообщает ему прекратить работу после завершения.

Очевидно, что вам нужно убедиться, что вы не запускаете проблемы синхронизации, если вы получаете onResume сразу после onPause (т.е. пока поток по-прежнему занят сохранением).