Android: cохранение данных, когда пользователь поворачивает устройство

Проблема

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

Существует несколько подходов. Если все ваши данные содержат элементар­ные типы, состоят из объектов класса String или являются объектами класса Serializable, вы можете сохранить их с помощью метода onSavelnstanceState() в переданном объекте класса Bundle.

Другое решение позволяет вернуть один произвольный объект. Для сохранения некоторых значений необходимо переопределить метод onRetainNonConfigurationl nstance(), чтобы сохранить некоторые значения, и вызвать метод getLastNonConfigurationlnstance() в конце вашего метода onCreate(), чтобы увидеть, существует ли ранее сохраненное значение, и, если это так, присвоить свои поля соответствую­щим образом.

Обсуждение

Одно из решений - это использование метода onSavelnstanceState(), которое уже обсуждалось здесь.

Альтернативное решение - использование метода onRetainNonConfigurationlnstance().

Типом значения, возвращаемого методом getLastNonConfigurationlnstance(), является класс Object, поэтому вы можете вернуть из него любое значение, которое захотите. Возможно, вы захотите создать объект класса Мар или написать внутрен­ний класс для хранения значений, но часто проще передать ссылку на текущую активность, например, используя следующий код:

public class MyActivity extends Activity {
		...

        /** Возвращает отдельный токен, который будет храниться
        * между уничтожением и восстановлением объекта класса Enterprise.
        */

        @Override
        public Object onRetainNonConfigurationInstance() {
                return this;
        }

Предыдущий метод будет вызываться, когда система Android уничтожит вашу основную активность. Предположим, вы хотели сохранить ссылку на другой объ­ект, который обновлялся запущенной службой, на которую ссылается поле в вашем объекте класса Activity. Им может быть логическое значение, указывающее, ак­тивна ли служба. В предыдущем коде мы возвращаем ссылку на экземпляр клас­са Activity, в котором могут быть доступны все его поля (даже закрытые поля, поскольку исходящие и входящие объекты класса Activity имеют один и тот же класс). Например, в моем приложении для определения географических координат JPSTrack есть экземпляр класса FileSaver, который получает данные от службы оп­ределения местоположения. Я хочу, чтобы он продолжал получать координаты и сохранял их на диске, несмотря на поворот, вместо того чтобы перезапускать его при каждом вращении экрана. Вращение маловероятно, если устройство привязано к машине на приборной панели (как мы надеемся), но вполне вероятно, что во вре­мя определения координат пассажир или пешеход фотографирует местность или пишет заметку.

После того как система Android создаст новый экземпляр, она вызовет метод onCreate(), чтобы уведомить новый экземпляр о его создании. В методе onCreate() обычно выполняется активность, похожая на конструктор, например инициализация полей и назначение слушателей событий. Вам все равно нужно это делать, поэтому оставьте их без изменений. Однако в конце метода onCreate() вы должны добавить некоторый код, чтобы получить старый экземпляр, если он есть, и некоторые его важные поля. Код должен выглядеть как примере 1.

Пример 1. Метод onCreate()

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    saving = false;
    paused = false;

        // Другая инициализация...
        // Проверка, происходит ли прерывание, например при вращении
        Main old = (Main) getLastNonConfigurationInstance();
        if (old != null) {
            saving = old.saving;
            paused = old.paused;

            // This is the most important line: keep saving to same file!
            fileSaver = old.fileSaver;
            if (saving) {
                    fileNameLabel.setText(fileSaver.getFileName());
            }
        return;
        }

       // Вспомогательная функция ввода-вывода 
       fileSaver = new GPSFileSaver(...);
}

Объект fileSaver является крупным, поэтому мы хотим продолжать с ним ра­ботать, а не повторно создавать каждый раз. Если у нас нет старого экземпляра, мы создаем объект fileSaver только в самом конце метода onCreate(), поскольку в противном случае мы будем создавать новый объект, только чтобы заменить его на старый, который (по крайней мере) снижает производительность. Когда метод onCreate() заканчивает свою работу, мы не ссылаемся на старый экземпляр, поэто­му он должен иметь доступ к механизму сборки мусора Java. Конечным результатом является то, что активность, похоже, хорошо выполняется при поворотах экрана, не­смотря на его воссоздание.

Альтернативной возможностью является установка атрибута android:config Changes = orientation в вашем файле AndroidManifest.xml. Этот подход предо­твращает уничтожение и воссоздание активности, но обычно также предотвращает правильное отображение приложения в альбомном режиме и официально считается нежелательной практикой.

 

 

Вас заинтересует / Intresting for you:

Версии платформы Android
Версии платформы Android 2478 просмотров Илья Дергунов Sun, 04 Nov 2018, 14:44:59
О платформе Android
О платформе Android 4857 просмотров Илья Дергунов Mon, 29 Oct 2018, 17:07:02
Понимание архитектуры приложен...
Понимание архитектуры приложен... 2633 просмотров Илья Дергунов Mon, 29 Oct 2018, 17:31:25
Запросы разрешений от системы ...
Запросы разрешений от системы ... 4446 просмотров dbstalker Sun, 24 Feb 2019, 06:24:29
Войдите чтобы комментировать