onSaveInstanceState / onPause - подождите, пока состояние не будет полностью сохранено, прежде чем разрешить уничтожение процесса - PullRequest
8 голосов
/ 19 сентября 2011

Я работаю над своим первым приложением для Android.У него есть модель, которая сохраняется в базе данных, когда пользователь делает обновления.

Когда вызывается onSaveInsanceState, я хочу сохранить идентификатор, который можно использовать для загрузки документа, над которым работал пользователь, избаза данных.Но это может произойти только после того, как документ полностью попадет в базу данных.В некоторых случаях сохранение сложного документа может занять несколько секунд (я надеюсь, что это ускорится, как только я выйду из подробного выхода из системы, и при фактическом использовании сложный документ будет создаваться пользователем поэтапно, каждая из которыхбудет сохранен в базе данных, так что маловероятно, что сложный документ придется сохранять за один раз)UI thread ", поэтому, конечно, взаимодействие с БД происходит в отдельном потоке.Но мое понимание жизненного цикла Android состоит в том, что во многих случаях вызывается onSaveInstanceState, потому что система Android хочет завершить процесс.Это говорит о том, что я не могу позволить этому методу возвращаться до тех пор, пока поток БД не закончит сохранение документа (и на самом деле с моим текущим дизайном я фактически не знаю, каков номер документа, пока он не будет сохранен в БД,поэтому я даже не могу поместить это в пакет сохраненного состояния).

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

Но onSaveInstanceState также вызывается, когда выполняется экземпляр Activityуничтожается обновлением конфигурации, которое происходит при изменении ориентации экрана.Это очень прискорбно, когда поворот экрана в сторону не дает ничего сделать в течение нескольких секунд.В этом случае процесс (и, следовательно, пространство памяти) все еще существует, поэтому мне не нужно строго следить за тем, чтобы документ попадал в базу данных, если я могу просто сохранить ссылку на него в Bundle вместо его идентификатора.Но я не знаю, как определить разницу между этими двумя случаями.

Есть ли общепринятая практика для этих ситуаций?Должен ли я просто заблокировать поток, чтобы быть безопасным?Могу ли я просто использовать обычные примитивы потоков Java для блокировки и ожидания?Могу ли я что-то сделать, чтобы не не блокировал поток, но гарантировал, что задача сохранения будет завершена до того, как Android закроет процесс?

Все это также относится к onPause, так как onSaveInstanceState не обязательно будет называться.

Ответы [ 2 ]

2 голосов
/ 19 сентября 2011

Вам не нужно делать постоянное сохранение в onSaveInstanceState, вы можете просто сохранить состояние экземпляра в Bundle, чтобы экземпляр можно было быстро возобновить в onRestoreInstanceState.

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

Я думаю, что моя рекомендация заключается в том, чтобы просто сохранить текст документа и все, что находится в Пакете в onSaveInstanceState и восстановить его в onRestoreInstanceState. Используйте onPause, чтобы быстро сохранить «резервную копию» (временный файл?), Которую затем можно восстановить в onResume, если она не была сохранена в базе данных. И используйте onStop (который вызывается, когда действие уже находится в фоновом режиме) для фактического сохранения данных в базе данных.

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

Редактировать - Дополнительно на основе комментариев

Чтобы убедиться, что фоновый поток, выполняющий процесс сохранения, сохранен до того, как система может быть уничтожена приложением, Я думаю, нормально заблокировать и дождаться завершения потока сохранения, прежде чем вернуться из onPause, но я рекомендую использовать android:configChanges="orientation" для предотвращения перезапуска активности (и onPause call) при изменении ориентации.

0 голосов
/ 19 сентября 2011

Вы должны попробовать AsyncTask, который заблокирует ваш пользовательский интерфейс, но не покажет пустой экран, загрузит необходимые элементы xml и затем получит вызов из задачи Async, в асинхронной задаче сохраните документ в базе данных.

Перейдите по этой ссылке: AyncTask Exmaple

...