Пошаговое руководство. Сохранение состояния действия

Мы рассмотрели теорию сохранения состояния в руководстве по жизненному циклу действий; Теперь рассмотрим пример.

Пошаговое руководство по состоянию действия

Давайте открываем проект ActivityLifecycle_Start , создадим его и запустите его. Это очень простой проект с двумя действиями для демонстрации жизненного цикла действий и вызова различных методов жизненного цикла. При запуске приложения отображается экран MainActivity :

Экран действия A

Просмотр переходов состояния

Каждый метод в этом примере записывается в окно вывода приложения интегрированной среды разработки, чтобы указать состояние действия. (Чтобы открыть окно вывода в Visual Studio, введите CTRL-ALT-O; чтобы открыть окно вывода в Visual Studio для Mac, щелкните View > Pads > Application Output.)

При первом запуске приложения в окне вывода отображаются изменения состояния действия A:

[ActivityLifecycle.MainActivity] Activity A - OnCreate
[ActivityLifecycle.MainActivity] Activity A - OnStart
[ActivityLifecycle.MainActivity] Activity A - OnResume

Когда мы нажимаем кнопку "Пуск действия Б", мы видим, что действие A приостанавливается и останавливается, пока действие B проходит через изменения состояния:

[ActivityLifecycle.MainActivity] Activity A - OnPause
[ActivityLifecycle.SecondActivity] Activity B - OnCreate
[ActivityLifecycle.SecondActivity] Activity B - OnStart
[ActivityLifecycle.SecondActivity] Activity B - OnResume
[ActivityLifecycle.MainActivity] Activity A - OnStop

В результате действие B запускается и отображается вместо действия A:

Экран

При нажатии кнопки "Назад" действие B уничтожается, а действие А возобновляется:

[ActivityLifecycle.SecondActivity] Activity B - OnPause
[ActivityLifecycle.MainActivity] Activity A - OnRestart
[ActivityLifecycle.MainActivity] Activity A - OnStart
[ActivityLifecycle.MainActivity] Activity A - OnResume
[ActivityLifecycle.SecondActivity] Activity B - OnStop
[ActivityLifecycle.SecondActivity] Activity B - OnDestroy

Добавление счетчика щелчка

Затем мы изменим приложение так, чтобы у нас была кнопка, которая подсчитывает и отображает количество нажатий. Сначала добавим переменную MainActivityэкземпляра _counter в:

int _counter = 0;

Затем давайте отредактируем файл макета resource/layout/Main.axml и добавьте новый clickButton , который отображает количество раз, когда пользователь нажимал кнопку. Результирующий файл Main.axml должен выглядеть следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <Button
        android:id="@+id/myButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/mybutton_text" />
    <Button
        android:id="@+id/clickButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/counterbutton_text" />
</LinearLayout>

Давайте добавим следующий код в конец метода OnCreate в MainActivity : этот код обрабатывает события щелчка изclickButton:

var clickbutton = FindViewById<Button> (Resource.Id.clickButton);
clickbutton.Text = Resources.GetString (
    Resource.String.counterbutton_text, _counter);
clickbutton.Click += (object sender, System.EventArgs e) =>
{
    _counter++;
    clickbutton.Text = Resources.GetString (
        Resource.String.counterbutton_text, _counter);
} ;

Когда мы создадим и снова запустите приложение, появится новая кнопка, которая увеличивается и отображает значение каждого щелчка _counter :

Добавление счетчика касаний

Но при смене устройства в альбомный режим это число теряется:

Поворот в альбомную группу задает значение счетчика назад к нулю

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

[ActivityLifecycle.MainActivity] Activity A - OnPause
[ActivityLifecycle.MainActivity] Activity A - OnStop
[ActivityLifecycle.MainActivity] Activity A - On Destroy

[ActivityLifecycle.MainActivity] Activity A - OnCreate
[ActivityLifecycle.MainActivity] Activity A - OnStart
[ActivityLifecycle.MainActivity] Activity A - OnResume

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

Добавление кода для сохранения состояния экземпляра

Давайте добавим метод для MainActivity сохранения состояния экземпляра. Перед уничтожением действия A Android автоматически вызывает OnSaveInstanceState и передает пакет, который можно использовать для хранения состояния экземпляра. Давайте будем использовать его для сохранения числа щелчков в качестве целочисленного значения:

protected override void OnSaveInstanceState (Bundle outState)
{
    outState.PutInt ("click_count", _counter);
    Log.Debug(GetType().FullName, "Activity A - Saving instance state");

    // always call the base implementation!
    base.OnSaveInstanceState (outState);    
}

Когда действие A повторно создано и возобновляется, Android передает это Bundle обратно в наш OnCreate метод. Давайте добавим код для OnCreate восстановления _counter значения из переданного.Bundle Добавьте следующий код непосредственно перед строкой, в которой clickbutton определена:

if (bundle != null)
{
    _counter = bundle.GetInt ("click_count", 0);
    Log.Debug(GetType().FullName, "Activity A - Recovered instance state");
}

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

Поворот экрана показывает количество четырех сохраненных

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

[ActivityLifecycle.MainActivity] Activity A - OnPause
[ActivityLifecycle.MainActivity] Activity A - Saving instance state
[ActivityLifecycle.MainActivity] Activity A - OnStop
[ActivityLifecycle.MainActivity] Activity A - On Destroy

[ActivityLifecycle.MainActivity] Activity A - OnCreate
[ActivityLifecycle.MainActivity] Activity A - Recovered instance state
[ActivityLifecycle.MainActivity] Activity A - OnStart
[ActivityLifecycle.MainActivity] Activity A - OnResume

Перед вызовом метода OnStop был вызван новый OnSaveInstanceState метод, чтобы сохранить _counter значение в объекте Bundle. Android передал это Bundle обратно нам, когда он вызвал наш OnCreate метод, и мы смогли использовать его для восстановления _counter значения, в которое мы оставили.

Итоги

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