Как обращаться с сохраненными данными после того, как Activity выходит на первый план при использовании более чем одного Activity? - PullRequest
4 голосов
/ 03 января 2012

В настоящий момент я немного запутался в управлении жизненным циклом в Android.Существует как минимум 4 возможности возобновить сохраненные данные после возвращения Действия на передний план:

  • Обработка Android: Если памяти достаточно, Android хранит и возобновляетважные данные (отмеченные переключателями, текст EditText, -... и т. д.) после перезапуска действия, пользователь находится в том же состоянии, что и раньше, когда действие перешло в фоновый режим.

  • onPause, onResume: Переопределение onPause, сохранение важных данных в базе данных или текстовом файле и возобновление их при следующем запуске onResume.

  • onSavedInstance (Bundle), onRestoreInstance (Bundle): Я могу сохранить данные в виде пары ключ-значение в пакеты и восстановить их после выполнения onRestoreInstance.

  • onRetainNonConfigurationInstance (), getLastNonConfigurationInstance (): Я решаю все проблемы с хранилищем в одном большом объекте и считываю getLastNonConfigurationInstance () при выполнении onCreate.

Хотя это сбивает с толку, какой подход лучше, я думаю, он полагается на опыт разработки, чтобы знать, когда использовать какую возможность.Если бы у вас было несколько хороших примеров для каждого, я был бы рад, но это не мой вопрос.Интересно, как справиться со всем этим, когда у меня есть разные действия, и одно действие будет убито Android, когда он остановится в фоновом режиме:

В моем случае у меня есть MainActivity и MessageActivity.MessageActivity состоит из ViewSwitcher, который состоит из двух состояний.Государство один - список выбора переключателей.Состояние два - это EditText с двумя кнопками (отправить и отменить).Когда я тестирую каждое состояние, нажимаю кнопку «Домой» на Android и перезагружаю приложение, правильная активность с нужным состоянием и старыми данными выходит на первый план, когда я оставляю обработку на Android.Так что это работает.
Но что происходит, когда Android разрушает MessageActivity в фоновом режиме: если я использую способ Android, данные будут потеряны, и я предполагаю, что MainActivity (вместо MessageActivity-> state (1 или 2)) запустится в следующий разпосле перезапуска приложения (это правильно?).Поэтому, когда я хочу сохранить данные MessageActivity, я должен использовать одну из трех других возможностей.
Как сделать это аккуратно, когда точка входа приложения (так что MainActivity) отличается от последней активной Activity.Проблема в том, что мне нужно возобновить специальную активность с особым состоянием ViewSwitcher.Я мог бы запустить MessageActivity из MainActivity с помощью startActivity (Intent) в методе onStart () или onResume () (поскольку MainActivity, вероятно, является точкой входа), но затем я столкнулся с множеством логических проблем в управлении жизненным циклом.В связи с этим я не думаю, что это правильный способ сделать это.

Но какой правильный и лучший способ сделать это?

Ответы [ 4 ]

2 голосов
/ 05 января 2012

Это не моя попытка получить лучший ответ, но я слишком долго вхожу в раздел комментариев.

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

Я предлагаю сохранять зависимые от состояния данные в парах ключ-значение в SharedPreferences каждый раз, когда вы входите в onPause() в вашем MessageActivity.Сохраните флаг в SharedPreferences, который указывает, какое действие было последним открытым (если у вас есть только два действия, вы можете легко перейти к флагам 0/1 или true / false).Когда вы перезапускаете свое приложение, обычно запускается действие, помеченное в вашем AndroidManifest.xml как «точка входа».Поэтому, естественно, вы отметите флаг в onResume() в вашем MainActivity и при необходимости запустите другое действие.В MessageActivity's onResume() проверьте значения в SharedPreferences и заполните все, что необходимо ... Если ваше приложение "возобновлено" до последнего действия в ActivityStack , это вызовет onResume() в Последнее действие в стэке ActivityStack .

2 голосов
/ 06 января 2012

Полагаю, что MainActivity (вместо MessageActivity-> state (1 или 2)) запустится в следующий раз после перезапуска приложения (это правильно?)

Нет, я не знаюне верю, что это правильно, в зависимости от того, что ваш код делает в onCreate ().Конечно, не нужно , чтобы быть правильным, если вы поступите правильно.Простой способ проверить это - повернуть экран, на котором воссоздаются текущие действия, если только вы не изменили поведение изменения конфигурации по умолчанию.

Я рекомендую внимательно прочитать этот раздел в документации для Android:

http://developer.android.com/guide/topics/fundamentals/activities.html#SavingActivityState

В частности:

, даже если вы ничего не делаете и не реализуете onSaveInstanceState (), часть состояния активности восстанавливается стандартной реализацией класса Activity onSaveInstanceState().В частности, реализация по умолчанию вызывает onSaveInstanceState () для каждого представления в макете, что позволяет каждому представлению предоставлять информацию о себе, которая должна быть сохранена.Почти каждый виджет в платформе Android реализует этот метод соответствующим образом, так что любые видимые изменения в пользовательском интерфейсе автоматически сохраняются и восстанавливаются при воссоздании вашей деятельности.Например, виджет EditText сохраняет любой текст, введенный пользователем, а виджет CheckBox сохраняет независимо от того, отмечен он или нет.Единственное, что от вас требуется - предоставить уникальный идентификатор (с атрибутом android: id) для каждого виджета, для которого вы хотите сохранить его состояние.Если у виджета нет идентификатора, он не может сохранить свое состояние.

Это означает, что если вы не вводите какое-либо состояние пользовательского интерфейса при любых вызовах onCreate(), вашСтек активности и состояние пользовательского интерфейса будут восстановлены.

Лично мой предпочтительный подход - сохранять как можно меньше состояний в переменных-членах моих действий, сохранять и восстанавливать его с помощью onSave/RestoreInstanceState() и полагаться на реализации по умолчаниюсохранить оставшуюся часть пользовательского интерфейса (текстовое поле и т. д.).Данные, которые должны сохраняться между сессиями, я фиксирую прямо в своей БД или настройках, как только она изменяется (например, в обработчике по нажатию).Это означает, что мне не нужно беспокоиться о жизненном цикле активности для этого.В максимально возможной степени мой пользовательский интерфейс просто отображает данные в моей БД (с использованием CursorAdapter и т.stack:

Когда пользователь покидает задачу, нажав клавишу HOME, ... Система сохраняет состояние каждой активности в задаче.Если впоследствии пользователь возобновит задачу, выбрав значок запуска, который начал задачу, задача выходит на передний план и возобновляет действие в верхней части стека.

(см. http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html)

1 голос
/ 18 февраля 2012
login.setOnClickListener(new View.OnClickListener()      {
    public void onClick(View view)         {
        String name=username.getText().toString();
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = settings.edit();
        editor.putString("username", name);
        if(name.equals("xxx"))                 {
            Intent intent=new Intent(currentactivity.this,nextactivity.class);
            intent.putExtras(bundle);
            startActivityForResult(intent,0);
        }
    }
});
1 голос
/ 05 января 2012

Способ решения подобной проблемы в прошлом состоял в том, чтобы служба работала в фоновом режиме, которая обрабатывает поток информации от различных действий через Intents и слушателей (предпочтительно, так как они наиболее легко отделены друг от друга).решение), или если вы очень осторожны, и единственное жизнеспособное решение по какой-то причине - это сохранение данных с помощью прямого доступа к свойству или вызовов методов, вы также можете использовать статические свойства / методы для класса обслуживания.Однако я настоятельно рекомендую использовать метод Intent / listener, так как он, как правило, более гибкий, поточно-ориентированный и отсоединенный.Кроме того, разумно убедиться, что в любой момент времени ничего не происходит (другими словами, только использует этот сервис для обработки намерений), когда он не нужен, в противном случае Сервис будет склонен перегружать ЦП.время, а также оперативная память, когда это действительно не нужно.Некоторые ресурсы, на которые следует обратить внимание при таком подходе: IntentService и связанные с ним классы, включая суперкласс Service.IntentService, однако, стоит отметить еще несколько моментов, связанных с асинхронной обработкой Intent и т. Д., С которыми Service не поставляется автоматически.Надеюсь, это поможет вам!

...