Сохранение экземпляра базы данных Firebase [дубликат]

Я предпочитаю использовать селектор, и я применяю его в документе.

Это привязывается к документу и будет применяться к элементам, которые будут отображаться после загрузки страницы.

Например:

$(document).on("click", $(selector), function() {
    // Your code here
});
2297
задан Taryn 22 March 2017 в 17:20
поделиться

27 ответов

Вам необходимо переопределить onSaveInstanceState(Bundle savedInstanceState) и записать значения состояния приложения, которые вы хотите изменить, на параметр Bundle следующим образом:

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
  super.onSaveInstanceState(savedInstanceState);
  // Save UI state changes to the savedInstanceState.
  // This bundle will be passed to onCreate if the process is
  // killed and restarted.
  savedInstanceState.putBoolean("MyBoolean", true);
  savedInstanceState.putDouble("myDouble", 1.9);
  savedInstanceState.putInt("MyInt", 1);
  savedInstanceState.putString("MyString", "Welcome back to Android");
  // etc.
}

Связка - это по существу способ хранения NVP ( «Параметр Name-Value Pair»), и он будет передан в onCreate(), а также onRestoreInstanceState(), где вы извлечете такие значения:

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  // Restore UI state from the savedInstanceState.
  // This bundle has also been passed to onCreate.
  boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
  double myDouble = savedInstanceState.getDouble("myDouble");
  int myInt = savedInstanceState.getInt("MyInt");
  String myString = savedInstanceState.getString("MyString");
}

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

2283
ответ дан Sufian 19 August 2018 в 07:17
поделиться
  • 1
    Есть ли шанс, что это работает на телефоне, но не в эмуляторе? Кажется, я не могу получить ненулевое значение saveInstanceState. – Adam Jack 18 November 2009 в 23:39
  • 2
    У меня есть ArrayList точек, как сохранить все точки в этом списке массивов, а затем восстановить их? – AZ_ 29 November 2010 в 08:09
  • 3
    ОСТОРОЖНО: вам нужно вызвать super.onSaveInstanceState (savedInstanceState) перед добавлением ваших значений в Bundle, иначе они будут уничтожены на этом вызове (Droid X Android 2.2). – jkschneider 13 April 2011 в 19:59
  • 4
    Осторожно: в официальной документации указано, что вы должны сохранять важную информацию в onPause-Method, потому что метод onsaveinstance не является частью жизненного цикла Android. developer.android.com/reference/android/app/Activity.html – schlingel 19 June 2012 в 08:40
  • 5
    Этот факт фактически делает onSaveInstanceState почти бесполезным, за исключением случаев изменения ориентации экрана. Почти во всех других случаях вы никогда не сможете полагаться на него, и вам нужно будет вручную сохранить состояние пользовательского интерфейса в другом месте. Или запретить вашему приложению убить, переопределив поведение кнопки BACK. Я не понимаю, почему они даже сделали это в первую очередь. Полностью неинтуитивный. И вы не можете иметь этот комплект, который система дает вам, чтобы сохранить вещи, кроме этого самого конкретного метода. – chakrit 5 July 2013 в 12:25

Оба метода полезны и действительны, и оба они лучше всего подходят для разных сценариев:

  1. Пользователь завершает работу приложения и повторно открывает его позднее, но приложение необходимо перезагрузить данные от последнего сеанса - для этого требуется постоянный подход к хранению, такой как использование SQLite.
  2. Пользователь переключает приложение, а затем возвращается к оригиналу и хочет выбрать, где он остановился, - сохранить и восстановить данные пакета ( такие как данные состояния приложения) в onSaveInstanceState() и onRestoreInstanceState(), как правило, являются адекватными.

Если вы сохраняете данные состояния постоянным образом, его можно перезагрузить в onResume() или onCreate() (или фактически на любом вызове жизненного цикла). Это может быть или не быть желательным. Если вы храните его в пакете в InstanceState, то он является временным и подходит только для хранения данных для использования в одном сеансе пользователя (я использую термин сеанс свободно), но не между «сеансами».

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

59
ответ дан Amanda S 19 August 2018 в 07:17
поделиться
  • 1
    Как выбрать SQLite и Preferences при поиске постоянного хранилища? – Deco 24 February 2012 в 18:52

savedInstanceState предназначен только для сохранения состояния, связанного с текущим экземпляром Activity, например текущей информации о навигации или выборе, так что, если Android уничтожает и воссоздает действие, он может вернуться, как и раньше. См. Документацию для onCreate и onSaveInstanceState

. Для более долгого состояния рассмотрите возможность использования базы данных SQLite, файла или предпочтений. См. Сохранение постоянного состояния .

376
ответ дан Benoit Duffez 19 August 2018 в 07:17
поделиться
  • 1
    Когда сохраняется значениеInstanceState == null и когда оно не равно нулю? – Trojan.ZBOT 30 December 2013 в 00:20
  • 2
    savedInstanceState имеет значение null, когда система создает новый экземпляр вашего действия и не имеет значения null при его восстановлении. – Gabriel Câmara 15 January 2014 в 15:21
  • 3
    ... что ставит вопрос о , когда требуется создать новый экземпляр Activity. Некоторые способы выхода из приложения не создают пакет, поэтому необходимо создать новый экземпляр. Это основная проблема; это означает, что мы не можем полагаться на существование пучка и должны делать некоторые альтернативные способы постоянного хранения. Преимущество onSave / onRestoreInstanceState заключается в том, что это механизм, который система может выполнять внезапно , не потребляя много системных ресурсов. Поэтому полезно поддерживать это, а также иметь постоянное хранилище для более грациозного выхода из приложения. – ToolmakerSteve 19 September 2015 в 10:24

Не уверен, что мое решение не одобрено или нет, но я использую связанный сервис, чтобы сохранить состояние ViewModel. Сохраняете ли вы его в памяти в службе или сохраняете и извлекаете из базы данных SqlLite, зависит от ваших требований. Это то, что делают сервисы любого вкуса, они предоставляют такие услуги, как поддержание состояния приложения и абстрактная общая бизнес-логика.

Из-за ограничений памяти и обработки, присущих мобильным устройствам, я рассматриваю Android-представления аналогично веб-странице. Страница не поддерживает состояние, это только компонент уровня представления, единственная цель которого - представить состояние приложения и принять ввод пользователя. В последних тенденциях в архитектуре веб-приложений используется старый шаблон модели, представления, контроллера (MVC), где страница представляет собой представление, данные домена - это модель, а контроллер находится за веб-службой. Та же модель может использоваться в андроиде, когда представление хорошо ... Просмотр, модель - данные вашего домена, а Контроллер реализован как связанный с Android сервис. Всякий раз, когда вы хотите, чтобы представление взаимодействовало с контроллером, привязывайтесь к нему при запуске / возобновлении и отвязывайте при остановке / паузе.

Этот подход дает вам дополнительный бонус, обеспечивающий принцип Разделения Концерна в том смысле, что все вашей бизнес-логики приложения можно перенести в вашу службу, которая уменьшает дублируемую логику в нескольких представлениях и позволяет взгляду применять еще один важный принцип проектирования: «Единая ответственность».

6
ответ дан ComeIn 19 August 2018 в 07:17
поделиться

Это классическая «игра» разработки Android. Здесь есть два вопроса:

  • Существует тонкая ошибка Android Framework, которая значительно усложняет управление стеком приложений во время разработки, по крайней мере, в устаревших версиях (не совсем уверен, когда / когда / как это было исправлено) , Я буду обсуждать эту ошибку ниже.
  • «Обычный» или предполагаемый способ решения этой проблемы сам по себе является довольно сложным с двойственностью onPause / onResume и onSaveInstanceState / onRestoreInstanceState

Просматривая все эти потоки, я подозреваю, что большую часть времени разработчики говорят об этих двух разных проблемах одновременно ... следовательно, вся путаница и сообщения «это не работает для меня».

Во-первых, для уточнения «предполагаемого» поведения: onSaveInstance и onRestoreInstance являются хрупкими и только для переходного состояния. Предполагаемое использование (afaict) - это обработка активности при повороте телефона (изменение ориентации). Другими словами, предполагаемое использование - это когда ваша активность по-прежнему логически «сверху», но все же должна быть восстановлена ​​системой. Сохраненный пакет не сохраняется за пределами процесса / памяти / gc, поэтому вы не можете положиться на это, если ваша деятельность переходит на задний план. Да, возможно, память вашей активности выдержит свою поездку на задний план и выйдет из GC, но это ненадежно (и это не предсказуемо).

Итак, если у вас есть сценарий, где есть смысл «пользовательский прогресс», или состояние, которое должно сохраняться между «запусками» вашего приложения, руководство должно использовать onPause и onResume. Вы должны сами выбрать и подготовить постоянный магазин.

НО - есть очень запутанная ошибка, которая усложняет все это. Подробности здесь:

http://code.google.com/p/android/issues/detail?id=2373

http : //code.google.com/p/android/issues/detail? id = 5277

В принципе, если ваше приложение запущено с флагом SingleTask, а затем вы запускаете его из главного экрана или меню запуска, то последующий вызов создаст новую задачу ... у вас будет фактически два разных экземпляра вашего приложения, населяющих один и тот же стек ..., который становится очень странным очень быстро. Это происходит, когда вы запускаете свое приложение во время разработки (т. Е. Из Eclipse или Intellij), поэтому разработчики часто сталкиваются с этим.

Я сражался через эти потоки в течение нескольких часов, прежде чем понял, что моей основной проблемой была эта ошибка, а не предполагаемое поведение каркаса , Отличный способ записи и обхода (UPDATE: см. Ниже), по-видимому, принадлежит пользователю @kaciula в этом ответе:

Домашнее нажатие клавиши

UPDATE Июнь 2013 г. : Через несколько месяцев я наконец нашел правильное решение. Вам не нужно самостоятельно управлять любыми флагами с установленными состояниями, а вы можете обнаружить это из фреймворка и поручиться соответствующим образом. Я использую это в начале моего LauncherActivity.onCreate:

if (!isTaskRoot()) {
    Intent intent = getIntent();
    String action = intent.getAction();
    if (intent.hasCategory(Intent.CATEGORY_LAUNCHER) && action != null && action.equals(Intent.ACTION_MAIN)) {
        finish();
        return;
    }
}
127
ответ дан Community 19 August 2018 в 07:17
поделиться
  • 1
    Почему Android снова стал мобильным оператором второго выбора? зарывает голову руками – Nick Bauer 15 October 2017 в 20:37

Мой коллега написал статью, объясняющую состояние приложения на устройствах Android, включая пояснения по жизненному циклу активности и информации о состоянии, сохранению информации о состоянии и сохранению состояния Bundle и SharedPreferences и . .

В статье рассматриваются три подхода:

Хранить данные локального varible / UI-управления для времени жизни приложения (т.е. временно) с использованием пакета состояний экземпляра

[Code sample – Store State in State Bundle]
@Override
public void onSaveInstanceState(Bundle savedInstanceState) 
{
  // Store UI state to the savedInstanceState.
  // This bundle will be passed to onCreate on next call.  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();

  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();

  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();

  savedInstanceState.putString(“Name”, strName);
  savedInstanceState.putString(“Email”, strEmail);
  savedInstanceState.putBoolean(“TandC”, blnTandC);

  super.onSaveInstanceState(savedInstanceState);
}

Хранить данные локального varible / UI-управления между экземплярами приложения (то есть постоянно) с использованием общих настроек

[Code sample – Store State in SharedPreferences]
@Override
protected void onPause() 
{
  super.onPause();

  // Store values between instances here
  SharedPreferences preferences = getPreferences(MODE_PRIVATE);
  SharedPreferences.Editor editor = preferences.edit();  // Put the values from the UI
  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();

  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();

  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();

  editor.putString(“Name”, strName); // value to store
  editor.putString(“Email”, strEmail); // value to store
  editor.putBoolean(“TandC”, blnTandC); // value to store    
  // Commit to storage
  editor.commit();
}

Сохранение экземпляров объектов в памяти между действиями в течение жизненного цикла приложения с использованием сохраненного экземпляра неконфигурации

[Code sample – store object instance]
private cMyClassType moInstanceOfAClass;// Store the instance of an object
@Override
public Object onRetainNonConfigurationInstance() 
{
  if (moInstanceOfAClass != null) // Check that the object exists
      return(moInstanceOfAClass);
  return super.onRetainNonConfigurationInstance();
}
174
ответ дан Gordon 19 August 2018 в 07:17
поделиться
  • 1
    @ MartinBelcher-Eigo В статье говорится о данных в SharedPreferences, которые «Эти данные записываются в базу данных на устройстве». Я считаю, что данные хранятся в файле в каталоге приложения файловой системы. – Tom 27 November 2012 в 00:43
  • 2
    Данные @Tom SharefPrefs записываются в файл xml. Является ли xml своего рода базой данных? Я бы сказал, что это так) – MaciejGórski 2 May 2013 в 11:35
  • 3
    Обратите внимание, что editor.apply() быстрее, чем editor.commit(). – Fred 9 July 2014 в 21:35
  • 4
    Ссылка мертва. – Sakiboy 26 February 2017 в 06:43

Чтобы ответить на исходный вопрос напрямую. savedInstancestate имеет значение null, поскольку ваша активность никогда не воссоздается.

Ваша активность будет воссоздана только с помощью пакета состояний, когда:

  • Изменения конфигурации, такие как изменение ориентация или язык телефона, для которого может потребоваться создание нового экземпляра активности.
  • Вы возвращаетесь в приложение из фона после того, как ОС уничтожила действие.

Android будет уничтожать фоновые действия, когда под давлением памяти или после того, как они были в фоновом режиме в течение длительного периода времени.

При тестировании вашего приветственного примера мира есть несколько способов выйти и вернуться к Activity.

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

В большинстве случаев, если вы просто нажимаете на кнопку «домой» и затем снова запускаете приложение, активность не нужно будет воссоздавать. Он уже существует в памяти, поэтому onCreate () не будет вызываться.

В разделе «Настройки» -> «Параметры разработчика» есть опция «Не выполнять действия». Когда это будет включено, Android всегда будет уничтожать действия и воссоздавать их, когда они будут созданы. Это отличный вариант оставить включенным при разработке, поскольку он имитирует худший сценарий. (Устройство с низкой памятью постоянно перерабатывает ваши действия).

Другие ответы ценны тем, что они учат вас правильным способам хранения состояния, но я не чувствовал, что они действительно ответили. ПОЧЕМУ ваш код не был " т работая так, как вы ожидали.

25
ответ дан Jared Kells 19 August 2018 в 07:17
поделиться

Чтобы помочь уменьшить шаблон, я использую следующие interface и class для чтения / записи в Bundle для сохранения состояния экземпляра.


Сначала создайте интерфейс, который будет используется для аннотирования ваших переменных экземпляра:

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({
        ElementType.FIELD
})
public @interface SaveInstance {

}

Затем создайте класс, в котором отражение будет использоваться для сохранения значений в комплекте:

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;

import java.io.Serializable;
import java.lang.reflect.Field;

/**
 * Save and load fields to/from a {@link Bundle}. All fields should be annotated with {@link
 * SaveInstance}.</p>
 */
public class Icicle {

    private static final String TAG = "Icicle";

    /**
     * Find all fields with the {@link SaveInstance} annotation and add them to the {@link Bundle}.
     *
     * @param outState
     *         The bundle from {@link Activity#onSaveInstanceState(Bundle)} or {@link
     *         Fragment#onSaveInstanceState(Bundle)}
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @see #load(Bundle, Object)
     */
    public static void save(Bundle outState, Object classInstance) {
        save(outState, classInstance, classInstance.getClass());
    }

    /**
     * Find all fields with the {@link SaveInstance} annotation and add them to the {@link Bundle}.
     *
     * @param outState
     *         The bundle from {@link Activity#onSaveInstanceState(Bundle)} or {@link
     *         Fragment#onSaveInstanceState(Bundle)}
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @param baseClass
     *         Base class, used to get all superclasses of the instance.
     * @see #load(Bundle, Object, Class)
     */
    public static void save(Bundle outState, Object classInstance, Class<?> baseClass) {
        if (outState == null) {
            return;
        }
        Class<?> clazz = classInstance.getClass();
        while (baseClass.isAssignableFrom(clazz)) {
            String className = clazz.getName();
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(SaveInstance.class)) {
                    field.setAccessible(true);
                    String key = className + "#" + field.getName();
                    try {
                        Object value = field.get(classInstance);
                        if (value instanceof Parcelable) {
                            outState.putParcelable(key, (Parcelable) value);
                        } else if (value instanceof Serializable) {
                            outState.putSerializable(key, (Serializable) value);
                        }
                    } catch (Throwable t) {
                        Log.d(TAG, "The field '" + key + "' was not added to the bundle");
                    }
                }
            }
            clazz = clazz.getSuperclass();
        }
    }

    /**
     * Load all saved fields that have the {@link SaveInstance} annotation.
     *
     * @param savedInstanceState
     *         The saved-instance {@link Bundle} from an {@link Activity} or {@link Fragment}.
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @see #save(Bundle, Object)
     */
    public static void load(Bundle savedInstanceState, Object classInstance) {
        load(savedInstanceState, classInstance, classInstance.getClass());
    }

    /**
     * Load all saved fields that have the {@link SaveInstance} annotation.
     *
     * @param savedInstanceState
     *         The saved-instance {@link Bundle} from an {@link Activity} or {@link Fragment}.
     * @param classInstance
     *         The object to access the fields which have the {@link SaveInstance} annotation.
     * @param baseClass
     *         Base class, used to get all superclasses of the instance.
     * @see #save(Bundle, Object, Class)
     */
    public static void load(Bundle savedInstanceState, Object classInstance, Class<?> baseClass) {
        if (savedInstanceState == null) {
            return;
        }
        Class<?> clazz = classInstance.getClass();
        while (baseClass.isAssignableFrom(clazz)) {
            String className = clazz.getName();
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(SaveInstance.class)) {
                    String key = className + "#" + field.getName();
                    field.setAccessible(true);
                    try {
                        Object fieldVal = savedInstanceState.get(key);
                        if (fieldVal != null) {
                            field.set(classInstance, fieldVal);
                        }
                    } catch (Throwable t) {
                        Log.d(TAG, "The field '" + key + "' was not retrieved from the bundle");
                    }
                }
            }
            clazz = clazz.getSuperclass();
        }
    }

}

Пример использования:

public class MainActivity extends Activity {

    @SaveInstance
    private String foo;

    @SaveInstance
    private int bar;

    @SaveInstance
    private Intent baz;

    @SaveInstance
    private boolean qux;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Icicle.load(savedInstanceState, this);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Icicle.save(outState, this);
    }

}

Примечание. Этот код был адаптирован из проекта библиотеки с именем AndroidAutowire , который лицензируется в соответствии с лицензией MIT .

27
ответ дан Jared Rummler 19 August 2018 в 07:17
поделиться

onSaveInstanceState() для временных данных (восстановлено в onCreate() / onRestoreInstanceState()), onPause() для постоянных данных (восстановлено в onResume()). Из технических ресурсов Android:

onSaveInstanceState () вызывается Android, если действие остановлено и может быть убито до его возобновления! Это означает, что он должен хранить любое состояние, необходимое для повторной инициализации в том же состоянии, когда операция перезапускается. Это аналог метода onCreate (), и фактически пакет savedInstanceState Bundle, переданный в onCreate (), представляет собой тот же Bundle, который вы создаете как outState в методе onSaveInstanceState ().

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

36
ответ дан Jorgesys 19 August 2018 в 07:17
поделиться

Хотя принятый ответ верен, есть более быстрый и простой способ сохранить состояние активности на Android, используя библиотеку под названием Icepick . Icepick - это обработчик аннотации, который заботится обо всех шаблонах, используемых для сохранения и восстановления состояния.

Выполнение чего-то подобного с помощью Icepick:

class MainActivity extends Activity {
  @State String username; // These will be automatically saved and restored
  @State String password;
  @State int age;

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Icepick.restoreInstanceState(this, savedInstanceState);
  }

  @Override public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Icepick.saveInstanceState(this, outState);
  }
}

То же самое, что и для этого:

class MainActivity extends Activity {
  String username;
  String password;
  int age;

  @Override
  public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    savedInstanceState.putString("MyString", username);
    savedInstanceState.putString("MyPassword", password);
    savedInstanceState.putInt("MyAge", age); 
    /* remember you would need to actually initialize these variables before putting it in the
    Bundle */
  }

  @Override
  public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    username = savedInstanceState.getString("MyString");
    password = savedInstanceState.getString("MyPassword");
    age = savedInstanceState.getInt("MyAge");
  }
}

Icepick будет работать с любым объектом, который сохраняет его состояние с Bundle.

12
ответ дан Kevin Cronly 19 August 2018 в 07:17
поделиться

Когда создается действие, вызывается метод onCreate ().

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

savedInstanceState является объектом класса Bundle, который является null в первый раз, но он содержит значения при его воссоздании. Чтобы сохранить состояние Activity, вы должны переопределить onSaveInstanceState ().

   @Override
    protected void onSaveInstanceState(Bundle outState) {
      outState.putString("key","Welcome Back")
        super.onSaveInstanceState(outState);       //save state
    }

поместить ваши значения в объект «outState» Bundle, такой как outState.putString («ключ», «приветствие назад») и сохранить, вызвав super , Когда действие будет уничтожено, его состояние будет сохранено в объекте Bundle и может быть восстановлено после отдыха в onCreate () или onRestoreInstanceState (). Пакет, полученный в onCreate () и onRestoreInstanceState (), одинаковый.

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

          //restore activity's state
         if(savedInstanceState!=null){
          String reStoredString=savedInstanceState.getString("key");
            }
    }

или

  //restores activity's saved state
 @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
      String restoredMessage=savedInstanceState.getString("key");
    }
11
ответ дан Mansuu.... 19 August 2018 в 07:17
поделиться

Методы onSaveInstanceState(bundle) и onRestoreInstanceState(bundle) полезны для сохранения данных только при повороте экрана (изменение ориентации). Они даже не хороши при переключении между приложениями (так как вызывается метод onSaveInstanceState(), но onCreate(bundle) и onRestoreInstanceState(bundle) снова не вызываются. Для большей настойчивости используйте общие настройки. читайте эту статью

23
ответ дан Mxyk 19 August 2018 в 07:17
поделиться
  • 1
    В вашем случае onCreate и onRestoreInstanceState не вызываются, потому что Activity вообще не уничтожается при переключении приложений, поэтому нет необходимости что-либо восстанавливать. Android вызывает onSaveInstanceState на случай, если действие будет уничтожено позже (что происходит со 100% уверенностью при повороте экрана, потому что вся конфигурация устройства была изменена, и активность должна быть воссоздана с нуля). – Vicky Chijwani 24 June 2015 в 23:21

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

Что-то вроде этого:

import java.util.Date;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class dataHelper {

    private static final String DATABASE_NAME = "autoMate.db";
    private static final int DATABASE_VERSION = 1;

    private Context context;
    private SQLiteDatabase db;
    private OpenHelper oh ;

    public dataHelper(Context context) {
        this.context = context;
        this.oh = new OpenHelper(this.context);
        this.db = oh.getWritableDatabase();
    }

    public void close()
    {
        db.close();
        oh.close();
        db = null;
        oh = null;
        SQLiteDatabase.releaseMemory();
    }


    public void setCode(String codeName, Object codeValue, String codeDataType)
    {
        Cursor codeRow = db.rawQuery("SELECT * FROM code WHERE codeName = '"+  codeName + "'", null);
        String cv = "" ;

        if (codeDataType.toLowerCase().trim().equals("long") == true)
        {
            cv = String.valueOf(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("int") == true)
        {
            cv = String.valueOf(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("date") == true)
        {
            cv = String.valueOf(((Date)codeValue).getTime());
        }
        else if (codeDataType.toLowerCase().trim().equals("boolean") == true)
        {
            String.valueOf(codeValue);
        }
        else
        {
            cv = String.valueOf(codeValue);
        }

        if(codeRow.getCount() > 0) //exists-- update
        {
            db.execSQL("update code set codeValue = '" + cv +
                "' where codeName = '" + codeName + "'");
        }
        else // does not exist, insert
        {
            db.execSQL("INSERT INTO code (codeName, codeValue, codeDataType) VALUES(" +
                    "'" + codeName + "'," +
                    "'" + cv + "'," +
                    "'" + codeDataType + "')" );
        }
    }

    public Object getCode(String codeName, Object defaultValue)
    {
        //Check to see if it already exists
        String codeValue = "";
        String codeDataType = "";
        boolean found = false;
        Cursor codeRow  = db.rawQuery("SELECT * FROM code WHERE codeName = '"+  codeName + "'", null);
        if (codeRow.moveToFirst())
        {
            codeValue = codeRow.getString(codeRow.getColumnIndex("codeValue"));
            codeDataType = codeRow.getString(codeRow.getColumnIndex("codeDataType"));
            found = true;
        }

        if (found == false)
        {
            return defaultValue;
        }
        else if (codeDataType.toLowerCase().trim().equals("long") == true)
        {
            if (codeValue.equals("") == true)
            {
                return (long)0;
            }
            return Long.parseLong(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("int") == true)
        {
            if (codeValue.equals("") == true)
            {
                return (int)0;
            }
            return Integer.parseInt(codeValue);
        }
        else if (codeDataType.toLowerCase().trim().equals("date") == true)
        {
            if (codeValue.equals("") == true)
            {
                return null;
            }
            return new Date(Long.parseLong(codeValue));
        }
        else if (codeDataType.toLowerCase().trim().equals("boolean") == true)
        {
            if (codeValue.equals("") == true)
            {
                return false;
            }
            return Boolean.parseBoolean(codeValue);
        }
        else
        {
            return (String)codeValue;
        }
    }


    private static class OpenHelper extends SQLiteOpenHelper {

        OpenHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE IF  NOT EXISTS code" +
            "(id INTEGER PRIMARY KEY, codeName TEXT, codeValue TEXT, codeDataType TEXT)");
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    }
}

Простой вызов после этого

dataHelper dh = new dataHelper(getBaseContext());
String status = (String) dh.getCode("appState", "safetyDisabled");
Date serviceStart = (Date) dh.getCode("serviceStartTime", null);
dh.close();
dh = null;
50
ответ дан Peter Mortensen 19 August 2018 в 07:17
поделиться
  • 1
    Поскольку для загрузки базы данных SQLite требуется слишком много времени, учитывая, что это критический путь для отображения пользовательского интерфейса приложения. Я на самом деле не приурочил его, поэтому я рад, что вас исправили, но, конечно, загрузка и открытие файла базы данных не будет быстрой? – Tom 27 November 2012 в 00:10
  • 2
    Большое вам спасибо за предоставление решения, которое новичок может вырезать и вставлять в свое приложение и использовать сразу же! @Tom. Что касается скорости, для хранения 1000 пар требуется около семи секунд, но вы можете сделать это в AsyncTask. Однако вам нужно добавить finally {cursor.close ()}, иначе он будет сбой при утечке памяти при этом. – Noumenon 4 May 2013 в 12:46
  • 3
    Я наткнулся на это, и, хотя это кажется аккуратным, я не решаюсь использовать это в Google Glass, которое я использую в последнее время. – Stephen Tetreault 31 October 2014 в 19:04

Действительно onSaveInstance status callen, когда Activity переходит в фоновый режим

Цитата из документов: «вызывается метод onSaveInstanceState(Bundle) перед размещением активности в таком фоновом состоянии»

70
ответ дан Praveenkumar 19 August 2018 в 07:17
поделиться
  • 1
    Извините, это не совсем правильно. onSaveInstanceState вызывается до того, как действие нужно будет переделать. т.е. каждый раз, когда пользователь поворачивает устройство. Он предназначен для хранения состояний переходного режима. Когда андроид заставляет приложение закрываться, onSaveInstanceState фактически НЕ вызывается (поэтому он небезопасен для хранения важных данных приложения). onPause, однако гарантируется, что он будет вызван до того, как действие будет убито, поэтому оно должно использоваться для хранения постоянной информации в настройках или Squlite. Правильный ответ, неправильные причины. – moveaway00 28 March 2012 в 05:06
  • 2
    @ moveaway00 - Частично неверно. Если система уничтожает приложение для восстановления ресурсов, он выполняет вызов onSaveInstanceState. Из developer.android.com/training/basics/activity-lifecycle/… - «Система также может уничтожить вашу деятельность ... для работы переднего плана требуется больше ресурсов, поэтому система должна отключить фоновый процессов для восстановления памяти. ... если система уничтожает активность из-за системных ограничений ... система помнит, что она существовала ... Сохраненные данные ... представляют собой набор пар ключ-значение, хранящихся в Bundle объект. & Quot ;. – ToolmakerSteve 19 September 2015 в 11:13

Код Котлина:

сохранить:

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState.apply {
        putInt("intKey", 1)
        putString("stringKey", "String Value")
        putParcelable("parcelableKey", parcelableObject)
    })
}

, а затем в onCreate() или onRestoreInstanceState()

    val restoredInt = savedInstanceState?.getInt("intKey") ?: 1 //default int
    val restoredString = savedInstanceState?.getString("stringKey") ?: "default string"
    val restoredParcelable = savedInstanceState?.getParcelable<ParcelableClass>("parcelableKey") ?: ParcelableClass() //default parcelable

Добавить значения по умолчанию, если вы не хотите иметь опции

6
ответ дан Rafols 19 August 2018 в 07:17
поделиться

Чтобы получить данные состояния активности, хранящиеся в onCreate(), сначала вам нужно сохранить данные в файле savedInstanceState, переопределив метод SaveInstanceState(Bundle savedInstanceState).

Когда вызывается вызов функции destroy SaveInstanceState(Bundle savedInstanceState), и там вы сохраняете данные вы хотите сохранить. И вы получите то же самое в onCreate(), когда перезагрузка активности. (SavedInstanceState не будет пустым, поскольку вы сохранили некоторые данные в нем до того, как действие будет уничтожено)

7
ответ дан Rahul Sharma 19 August 2018 в 07:17
поделиться

Воссоздание активности

Существует несколько сценариев, в которых ваша деятельность уничтожена из-за обычного поведения приложения, например, когда пользователь нажимает кнопку «Назад» или ваша активность сигнализирует о своем собственном уничтожении, вызывая finish(). Система также может уничтожить вашу деятельность, если она в настоящее время остановлена ​​и не использовалась в течение длительного времени, или для работы переднего плана требуется больше ресурсов, поэтому система должна отключить фоновые процессы для восстановления памяти.

Когда ваш activity уничтожается, потому что пользователь нажимает Back или activity заканчивается сам, концепция системы этого экземпляра Activity исчезает навсегда, потому что поведение указывает, что действие больше не требуется. Однако, если система уничтожает активность из-за системных ограничений (а не обычного поведения приложения), то, хотя фактический экземпляр Activity отсутствует, система помнит, что она существовала так, что если пользователь переходит к ней, система создает новый экземпляр действия с использованием набора сохраненных данных, который описывает состояние активности, когда он был destroyed. Сохраненные данные, которые система использует для восстановления предыдущего состояния, называются «статусом экземпляра» и представляют собой набор пар ключ-значение, хранящихся в объекте Bundle.

Чтобы сохранить дополнительные данные о состоянии активности, вы должны переопределить метод обратного вызова onSaveInstanceState (). Система вызывает этот метод, когда пользователь покидает вашу активность и передает ему объект Bundle, который будет сохранен в случае неожиданного уничтожения вашей активности. Если система должна воссоздать экземпляр активности позже, он передает тот же объект Bundle как для методов onRestoreInstanceState(), так и onCreate().

Когда система начинает останавливать вашу деятельность, она вызывает onSaveInstanceState() (1), поэтому вы можете указать дополнительные данные состояния, которые вы хотите сохранить, если экземпляр Activity должен воссоздаваться. Если активность уничтожена и один и тот же экземпляр должен быть воссоздан, система передает данные состояния, определенные в (1), как методу onCreate() (2), так и методу onRestoreInstanceState() (3).

Сохранить ваше Activity состояние

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

Чтобы сохранить дополнительную информацию о состоянии для вашей деятельности, вы должны реализовать onSaveInstanceState() и добавить пары ключ-значение в объект Bundle. Например:

  static final String STATE_SCORE = "playerScore";
  static final String STATE_LEVEL = "playerLevel";

  @Override
  public void onSaveInstanceState(Bundle savedInstanceState) {
  // Save the user's current game state
  savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
  savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel);

  // Always call the superclass so it can save the view hierarchy state
  super.onSaveInstanceState(savedInstanceState);
}

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

Восстановить ваше Activity состояние

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

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

Например, вот как вы можете восстановить некоторые данные состояния в onCreate():

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState); // Always call the superclass first

 // Check whether we're recreating a previously destroyed instance
 if (savedInstanceState != null) {
    // Restore value of members from saved state
    mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
    mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
 } else {
    // Probably initialize members with default values for a new instance
 }

 }

Вместо восстановления состояния во время onCreate() вы можете выбрать onRestoreInstanceState(), который система вызывает после метода onStart(). Система вызывает onRestoreInstanceState() только в случае сохранения сохраненного состояния, поэтому вам не нужно проверять, является ли Bundle нулевым:

  public void onRestoreInstanceState(Bundle savedInstanceState) {
  // Always call the superclass so it can restore the view hierarchy
  super.onRestoreInstanceState(savedInstanceState);

  // Restore state members from saved instance
  mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
  mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);
}
36
ответ дан Ravi Vaghela 19 August 2018 в 07:17
поделиться

Существует два способа реализации этого изменения:

  1. с использованием onSaveInstanceState() и onRestoreInstanceState().
  2. В манифесте android:configChanges="orientation|screenSize".

Я действительно не рекомендую использовать второй метод. Поскольку в одном из моих опытов он вызывал половину экрана устройства черным при повороте от портрета к пейзажу и наоборот.

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

Пример. Рассмотрим случай, если вы хотите сохранить объект Json. создать класс модели с геттерами и сеттерами.

class MyModel extends Serializable{
JSONObject obj;

setJsonObject(JsonObject obj)
{
this.obj=obj;
}

JSONObject getJsonObject()
return this.obj;
} 
}

Теперь в вашей деятельности в методе onCreate и onSaveInstanceState выполните следующее. Он будет выглядеть примерно так:

@override
onCreate(Bundle savedInstaceState){
MyModel data= (MyModel)savedInstaceState.getSerializable("yourkey")
JSONObject obj=data.getJsonObject();
//Here you have retained JSONObject and can use.
}


@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Obj is some json object 
MyModel dataToSave= new MyModel();
dataToSave.setJsonObject(obj);
oustate.putSerializable("yourkey",dataToSave); 

}
12
ответ дан Rubin Nellikunnathu 19 August 2018 в 07:17
поделиться

Вот комментарий от ответа Стива Мозли (by ToolmakerSteve), который ставит вещи в точку зрения (в целом onSaveInstanceState vs onPause, восточная стоимость и сага о западе)

@VVK - я частично не согласны. Некоторые способы выхода из приложения не запускают onSaveInstanceState (oSIS). Это ограничивает полезность ОСШ. Его стоит поддерживать для минимальных ресурсов ОС, но если приложение хочет вернуть пользователя в состояние, в котором они находились, вне зависимости от того, как приложение было выведено, вместо этого необходимо использовать подход с постоянным хранилищем. Я использую onCreate для проверки пакета, и если он отсутствует, проверьте целостность хранилища. Это централизует принятие решений. Я могу восстановиться после сбоя, или выйти из задней кнопки или пользовательского пункта меню «Выход», или вернуться к пользователю экрана через несколько дней. - ToolmakerSteve Сен 19 '15 в 10:38

9
ответ дан samsara 19 August 2018 в 07:17
поделиться

Тем временем я вообще не использую

Bundle savedInstanceState & Co

, живой цикл для большинства действий слишком сложный и не нужен. И google заявляет о себе, он НЕ является даже надежным.

Мой способ - сохранить любые изменения немедленно в настройках

 SharedPreferences p;
 p.edit().put(..).commit()

каким-то образом. SharedPreferences работают аналогично Bundles. И естественно, и сначала такие значения должны быть красными от предпочтений.

В случае сложных данных вы можете использовать Sqlite вместо использования предпочтений.

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

28
ответ дан stefan bachert 19 August 2018 в 07:17
поделиться

Кажется, я нашел ответ. Позвольте мне сказать, что я сделал простыми словами:

Предположим, что у меня есть два вида деятельности, activity1 и activity2, и я перемещаюсь из activity1 в activity2 (я сделал некоторые работы в activity2) и снова вернулся к активности 1 нажав на кнопку в действии1. Теперь на этом этапе я хотел вернуться к активности2, и я хочу увидеть свою активность2 в том же состоянии, когда я последний раз оставил activity2.

В приведенном выше сценарии я сделал то, что в манифесте, который я сделал некоторые изменения вроде этого:

<activity android:name=".activity2"
          android:alwaysRetainTaskState="true"      
          android:launchMode="singleInstance">
</activity>

И в действии1 на событии нажатия кнопки я сделал вот так:

Intent intent = new Intent();
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
intent.setClassName(this,"com.mainscreen.activity2");
startActivity(intent);

И в Activity2 на событии нажатия кнопки, которое я сделал например:

Intent intent=new Intent();
intent.setClassName(this,"com.mainscreen.activity1");
startActivity(intent);

Теперь, что произойдет, все изменения, которые мы внесли в Activity2, не будут потеряны, и мы можем просмотреть activity2 в том же состоянии, что и ранее.

Я считаю, что это ответ, и это отлично работает для меня. Исправьте меня, если я ошибаюсь.

50
ответ дан Stephen Tetreault 19 August 2018 в 07:17
поделиться
  • 1
    @bagusflyer заботится о том, чтобы быть более конкретным ??? Ваш комментарий не поможет, и никто не может помочь вам на этом основании. – Stephen Tetreault 31 October 2014 в 19:00
  • 2
    Это ответ на другую ситуацию: два действия в одном приложении. OP находится около , оставляя приложение (например, кнопку «домой» или другие способы переключения на другое приложение). – ToolmakerSteve 27 September 2015 в 07:41

Простой способ решить эту проблему с помощью IcePick

Сначала установите библиотеку в app/build.gradle

repositories {
  maven {url "https://clojars.org/repo/"}
}
dependencies {
  compile 'frankiesardo:icepick:3.2.0'
  provided 'frankiesardo:icepick-processor:3.2.0'
}

Теперь давайте проверим это пример ниже, как сохранить состояние в Activity

public class ExampleActivity extends Activity {
  @State String username; // This will be automatically saved and restored

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Icepick.restoreInstanceState(this, savedInstanceState);
  }

  @Override public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    Icepick.saveInstanceState(this, outState);
  }
}

Он работает для операций, фрагментов или любого объекта, который должен сериализовать свое состояние на Bundle (например, ViewPresenters минометов)

Icepick can также генерировать код состояния экземпляра для пользовательских представлений:

class CustomView extends View {
  @State int selectedPosition; // This will be automatically saved and restored

  @Override public Parcelable onSaveInstanceState() {
    return Icepick.saveInstanceState(this, super.onSaveInstanceState());
  }

  @Override public void onRestoreInstanceState(Parcelable state) {
    super.onRestoreInstanceState(Icepick.restoreInstanceState(this, state));
  }

  // You can put the calls to Icepick into a BaseCustomView and inherit from it
  // All Views extending this CustomView automatically have state saved/restored
}
6
ответ дан THANN Phearum 19 August 2018 в 07:17
поделиться
  • 1
    это работает для фрагмента? это сохраняет и восстанавливает состояние пользовательского представления? – ralphgabb 14 September 2016 в 02:21
  • 2
    @ralphspoon да, он работает для фрагмента и пользовательского вида. Проверьте пример кода. Я отредактировал свой ответ. Я предлагаю вам обратиться к официальным документам здесь github.com/frankiesardo/icepick , чтобы найти еще образец кода. – THANN Phearum 14 September 2016 в 02:28
  • 3
    плохо дать ему попробовать, я надеюсь, что вложенные фрагменты также поддерживаются. – ralphgabb 14 September 2016 в 05:22

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

mySavedInstanceState=savedInstanceState;

и использовать его для получения содержимого моей переменной, когда мне это нужно, в соответствии с:

if (mySavedInstanceState !=null) {
   boolean myVariable = mySavedInstanceState.getBoolean("MyVariable");
}

Я использовал onSaveInstanceState и onRestoreInstanceState, как было предложено выше, но я думаю, что я мог бы или в качестве альтернативы использовать мой метод для сохранения переменной при ее изменении (например, используя putBoolean)

15
ответ дан torwalker 19 August 2018 в 07:17
поделиться

Обратите внимание, что NOT безопасно использовать onSaveInstanceState и onRestoreInstanceState для постоянных данных в соответствии с документацией о статусах активности в http://developer.android.com/ reference / android / app / Activity.html .

В документе указано (в разделе «Жизненный цикл активности»):

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

В других слова, поместите ваш код сохранения / восстановления для постоянных данных в onPause() и onResume()!

EDIT: для дальнейшего уточнения, вот документация onSaveInstanceState():

Этот метод вызывается до того, как активность может быть убита, так что, когда она вернется через некоторое время в будущем, она сможет восстановить свое состояние. Например, если активность B запускается перед активностью A, и в какой-то момент активность A убивается для восстановления ресурсов, активность A будет иметь возможность сохранить текущее состояние своего пользовательского интерфейса с помощью этого метода, чтобы при возврате пользователя к действию A состояние пользовательского интерфейса может быть восстановлено через onCreate(Bundle) или onRestoreInstanceState(Bundle).

367
ответ дан Vicky Chijwani 19 August 2018 в 07:17
поделиться
  • 1
    Просто для nitpick: это тоже небезопасно. Это зависит только от того, что вы хотите сохранить и как долго, что @Bernard не совсем ясно в своем первоначальном вопросе. InstanceState идеально подходит для сохранения текущего состояния пользовательского интерфейса (данные, вводимые в элементы управления, текущие позиции в списках и т. Д.), Тогда как Pause / Resume - единственная возможность для долговременного постоянного хранения. – Pontus Gagge 24 June 2010 в 15:01
  • 2
    Это должно быть уменьшено. Небезопасно использовать в (Save | Restore) InstanceState, как методы жизненного цикла (т. Е. Делать что-то еще в них, кроме сохранения / восстановления состояния). Они отлично подходят для сохранения / восстановления состояния. Кроме того, как вы хотите сохранить / восстановить состояние в onPause и onResume? Вы не получаете Bundles в тех методах, которые вы можете использовать, поэтому вам придется использовать некоторые другие состояния, в базах данных, файлах и т. Д., Которые являются глупыми. – Felix 11 July 2010 в 11:10
  • 3
    Мы не должны проголосовать за этого человека, по крайней мере, он прилагал усилия для того, чтобы пройти документацию, и я думаю, что мы здесь, для того, чтобы на самом деле создавать знающие сообщества и помогать друг другу, а не DOWN VOTE. так что я проголосую за это, и я попрошу вас, чтобы люди не голодали, не голосовали или не голосовали .... этот человек очистил путаницу, которую хотелось бы иметь при прохождении документации. 1 голос вверх :) – AZ_ 26 November 2010 в 06:13
  • 4
    Я не думаю, что этот ответ заслуживает понижения. По крайней мере, он попытался ответить и процитировал раздел из doco. – GSree 5 January 2011 в 05:54
  • 5
    Этот ответ абсолютно правильный и заслуживает голосования, а не вниз! Позвольте мне уточнить разницу между государствами для тех парней, которые этого не видят. Состояние GUI, например выбранные радиокнопки и некоторый текст в поле ввода, гораздо менее важно, чем состояние данных, например записи, добавленные в список, отображаемый в ListView. Последний должен храниться в базе данных в onPause, потому что это единственный гарантированный звонок. Если вы поместите его в onSaveInstanceState, вы рискуете потерять данные, если это не вызвано. Но если выбор радиокнопки не сохраняется по той же причине - это не очень важно. – JBM 16 June 2011 в 16:15

onSaveInstanceState вызывается, когда система нуждается в памяти и убивает приложение. Он не вызывается, когда пользователь просто закрывает приложение. Поэтому я думаю, что состояние приложения также должно быть сохранено в onPause. Оно должно быть сохранено в каком-то постоянном хранилище, например Preferences или Sqlite

70
ответ дан Praveenkumar 19 August 2018 в 07:17
поделиться
  • 1
    Извините, это не совсем правильно. onSaveInstanceState вызывается до того, как действие нужно будет переделать. т.е. каждый раз, когда пользователь поворачивает устройство. Он предназначен для хранения состояний переходного режима. Когда андроид заставляет приложение закрываться, onSaveInstanceState фактически НЕ вызывается (поэтому он небезопасен для хранения важных данных приложения). onPause, однако гарантируется, что он будет вызван до того, как действие будет убито, поэтому оно должно использоваться для хранения постоянной информации в настройках или Squlite. Правильный ответ, неправильные причины. – moveaway00 28 March 2012 в 05:06
  • 2
    @ moveaway00 - Частично неверно. Если система уничтожает приложение для восстановления ресурсов, он выполняет вызов onSaveInstanceState. Из developer.android.com/training/basics/activity-lifecycle/… - «Система также может уничтожить вашу деятельность ... для работы переднего плана требуется больше ресурсов, поэтому система должна отключить фоновый процессов для восстановления памяти. ... если система уничтожает активность из-за системных ограничений ... система помнит, что она существовала ... Сохраненные данные ... представляют собой набор пар ключ-значение, хранящихся в Bundle объект. & Quot ;. – ToolmakerSteve 19 September 2015 в 11:13
1
ответ дан M Abdul Sami 30 October 2018 в 19:29
поделиться
0
ответ дан Shomu 30 October 2018 в 19:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: