Приложение и его жизненный цикл

Жизненный цикл приложения

Последнее обновление: 11.02.2016

Работа приложения UWP начинается с класса App, который определен в файлах App.xaml и App.xaml.cs. Класс App является входной точкой в приложение, обеспечивает управление жизненным циклом, а также управляет ресурсами, общими для всего приложения. Кроме того, в классе App можно перехватить исключения, которые могут возникнут в процессе работы. Фактически класс App и представляет приложение.

Приложение может пребывать в пяти различных состояниях:

  • NotRunning: это состояние возникает, когда пользователь впервые активирует приложение при его установки из магазина, либо когда пользователь закрывает приложение через диспетчер задач, либо завершает его работу, выключая компьютер или осуществляя выход из системы

  • Running: приложение запущено, и пользователь с ним взаимодействует

  • Suspended: работа приложения приостановлена, оно не активно

  • Terminated: работа приложения завершается. Переход в это состояние может быть произведен ОС Windows, если к примеру, приложение уже находится в приостановленном состоянии Suspended, но в связи с нехваткой памяти для других приложений оно переходится в состояние Terminated

  • ClosedByUser: состояние возникает при закрытии пользователем приложения на крестик или по нажатию клавиш Alt+F4

Переходы из одного состояния в другое можно описать следующей схемой:

Жизненный цикл приложения Universal Windows Platform

Первоначально приложение находится в состоянии NotRunning, оно не работает, и пользователь с ним не взаимодействует. Но вот пользователь нажимает на соответствующий значок или квадратик приложения, и приложение начинает запускаться, класс App, который представляет приложение, начинает работать. Вначале в этом классе вызывается метод OnLaunched(). Если приложение ранее было приостановлено, но пользователь вернулся к нему, то у него также вызывается метод OnLaunched(). Стандартное определение метода OnLaunched:

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    Frame rootFrame = Window.Current.Content as Frame;

    if (rootFrame == null)
    {
        rootFrame = new Frame();

        rootFrame.NavigationFailed += OnNavigationFailed;

        if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
        {
            //TODO: Load state from previously suspended application
        }

         Window.Current.Content = rootFrame;
    }

    if (e.PrelaunchActivated == false)
    {
        if (rootFrame.Content == null)
        {
            rootFrame.Navigate(typeof(MainPage), e.Arguments);
        }
        Window.Current.Activate();
    }
}

При вызове метода ему передается параметр типа LaunchActivatedEventArgs, который содержит информацию о предыдущем состоянии приложения, а также аргументы активации. Данный параметр может играть большое значение. Так, когда пользователь вызывает приложение, которое ранее было завершено системой и перешло в состояние Terminated, или которое было завершено пользователем и перешло в состояние ClosedByUser, то свойство PreviousExecutionState этого параметра имеет значения ApplicationExecutionState.Terminated или ApplicationExecutionState.ClosedByUser. А свойство Kind имеет значение ActivationKind.Launch.

Если предыдущее состояние равно ApplicationExecutionState.Terminated, то, возможно, имеет смысл загрузить ранее сохраненные данные. Собственно поэтому по умолчанию в код метода OnLaunched добавлена следующая конструкция:

if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
    //TODO: Load state from previously suspended application
}

Если же предыдущее состояние приложения было NotRunning, то приложение фактически стартует с чистого листа. То есть разработчик может быть уверен, что предыдущий запуск приложения не завершился прерыванием работы со стороны операционной системы.

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

Сразу после того, как приложение перейдет в состояние Running, срабатывает метод OnActivated(). По умолчанию в классе App этот метод не используется, но мы его можем переопределить. Например:

protected override void OnActivated(IActivatedEventArgs args)
{
    if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
    {
        // что-то сделать
    }
    base.OnActivated(args);
}

Здесь опять же мы можем получить из аргумента метода предыдущее состояние. Если оно представляет Terminated, то, к примеру, загрузить ранее сохраненные данные, либо выполнить какую-то другую работу.

Приостановка приложения

Когда пользователь переключается на другое приложение, либо на стартовый экран, происходит приостановка приложения. Если пользователь после этого вернется к ранее приостановленному приложению, то оно снова переходит в состояние Running. При этом переключение состояния происходит не сразу. Если пользователь переключился на другое приложение, то система ждет несколько секунд. И если пользователь в течение этого времени не вернулся в приложение, то оно переходит в состояние Suspended.

Все данные, которые были в приложении до приостановки, сохраняются системой и восстанавливаются при активизации приложения. Однако если данных слишком много, а доступной памяти для них нет, то приложение переводится системой в состояние Terminated и тем самым завершает свою работу. При этом система никак не уведомляет пользователя о том, что приложение было завершено. Поэтому имеет смысл сохранять критические данные в памяти устройства, чтобы после возобновления работы восстановить их в методе OnLaunched или OnActivated.

При переходе приложения в состояние Suspended генерируется событие Suspending. И если мы посмотрим на определение класса App, то увидим в нем обработчик, который вызывается при переходе приложения в состояние Suspended:

sealed partial class App : Application
{
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
    }
	
	// .....................
    private void OnSuspending(object sender, SuspendingEventArgs e)
    {
        var deferral = e.SuspendingOperation.GetDeferral();
        
		// здесь код, выполняющийся при приостановке приложения
        
		deferral.Complete();
    }
}

Как правило, в обработчике OnSuspending происходит сохранение важных данных приложения, что может спасти их от потери в случае перевода приложения в состояние Terminated. Также здесь можно освобождать некоторые ресурсы, которые могут связаны с камерой, устройствами ввода-вывода и т.д. И, что важно, выполнение кода в этом обработчике должно занимать очень мало времени, оптимально - не более 5 секунд, так как если обработчик будет выполняться несколько секунд, то система сочтет, что приложение перестало отвечать на запросы и должно быть переведено в состояние Terminated.

В начале в обработчике следует получить объект deferral: var deferral = e.SuspendingOperation.GetDeferral();. Этот объект позволит системе дать приложению время на выполнение асинхроннных операций.

После выполнения всех операций мы помечаем полученную задачу как завершенную с помощью вызова deferral.Complete()

Возобновление работы

Когда пользователь возвращается к ранее приостановленному приложению, оно вновь переходит в состояние Running. При этом генерируется событие Resuming. И если нам надо при этом выполнить некоторую логику, то мы можем обработать это событие:

sealed partial class App : Application
{
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
        this.Resuming += App_Resuming;
    }

    private void App_Resuming(object sender, object e)
    {
        // некоторый код
    }
}

Завершение работы

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

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850