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

Потеря данных при повороте экрана

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

4b9b3361

Ответ 1

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

Ответ 2

//Use onSaveInstanceState(Bundle) and onRestoreInstanceState

@Override
public void onSaveInstanceState(Bundle 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.  

  super.onSaveInstanceState(savedInstanceState);  
}  

//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");  
}

Так вы сохраняете свои данные, когда система удаляет их при вращении.

Ответ 4

Вот вариация на полезном ответе @jaisonDavis:

int myInt;
String myString;

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_verses);


    if (savedInstanceState == null) {

        Intent intent = getIntent();
        myInt = intent.getIntExtra("MyIntIntentKey", DEFAULT_INT);
        myString = intent.getStringExtra("MyStringIntentKey", DEFAULT_STRING);

    } else { // savedInstanceState has saved values

        myInt = savedInstanceState.getInt("MyIntKey");
        myString = savedInstanceState.getString("MyStringKey");
    }

}

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

    savedInstanceState.putInt("MyIntKey", myInt);
    savedInstanceState.putString("MyStringKey", myString);

    super.onSaveInstanceState(savedInstanceState);
}

В этом примере переменные инициализируются из Intent при первом создании операции, но после этого они инициализируются из savedInstanceState (например, при изменении ориентации).

Ответ 5

В AndroidManifest.xml добавьте следующий код

<activity android:name=".MainActivity" android:configChanges="keyboardHidden|orientation|screenSize" >

Ответ 6

Более детально

Люди уже предоставили код. Так что я собираюсь добавить более подробную информацию об этом.

Что происходит, когда экран вращается?

Когда экран поворачивается, конфигурация Действия изменяется, поэтому Система ищет более подходящий ресурс для Действия. Для этого система уничтожает экземпляр действия и воссоздает новый экземпляр действия.

Как система создает новый экземпляр?

Система пытается воссоздать экземпляр, используя набор сохраненных данных старого экземпляра Activity, известного как состояние экземпляра. InstanceState является коллекцией пары ключ-значение, хранящейся в объекте Bundle.

Система автоматически сохранила некоторые данные

По умолчанию система сохраняет объекты View, например, в Bundle.

  • Текст в EditText
  • Положение прокрутки в ListView и т.д.

Если вы хотите хранить больше данных, которые должны выжить, измените ориентацию. Вы должны переопределить onSaveInstanceState(Bundle savedInstanceState).

Используйте onSaveInstaneState правильно

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

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

Поэтому по ошибке, если вы забудете вызвать super.onSaveInstanceState(saveInstanceState), поведение по умолчанию не будет работать, т.е. текст в EditText не сохранится. Если вы мне не верите, проверьте это

Какой метод использовать для восстановления состояния?

Многие люди запутались, в том числе и я. Должен ли я выбрать

  • onCreate(Bundle savedInstanceState)

ИЛИ ЖЕ

  • onRestoreInstanceState(Bundle savedInstanceState)

Это не имеет значения. Оба метода получают один и тот же пакет в параметре. Единственное отличие состоит в том, что вам нужно предоставить нулевую проверку в onCreate(Bundle savedInstanceState). Но если вы собираетесь использовать onRestoreInstanceState(Bundle savedInstanceState), используйте его осторожно

@Override
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);
}

Всегда вызывайте super.onRestoreInstanceState(savedInstanceState) чтобы система по умолчанию восстановила иерархию представления

Ответ 7

setRetainInstance(true);

Используйте это в OnCreate

Ответ 8

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

Пожалуйста, обратитесь к документации

https://developer.android.com/topic/libraries/architecture/viewmodel

Ответ 9

В AndroidManifest.xml добавьте следующий код

<activity android:name=".MainActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            >

Меня устраивает

Ответ 10

Вы можете использовать шаблон MVVM и использовать вашу ViewModel для сохранения ваших данных. Поэтому, когда вы поворачиваете свое устройство, вы не будете беспокоиться о потере своих данных, потому что вы изолировали свои данные в ViewModel, и это означает, что ваши данные не будут затронуты жизненным циклом активности. https://developer.android.com/topic/libraries/architecture/viewmodel