Жизненный цикл приложения универсальной платформы Windows (UWP) для Windows 10

В этой статье рассказывается о жизненном цикле приложения универсальной платформы Windows (UWP) с момента его активации и до закрытия.

Немного истории

До выпуска Windows 8 у приложений был простой жизненный цикл. Приложения Win32 и .NET или работали, или не работали. Когда пользователь сворачивал их или переключался на другие задачи, они продолжали работу. Этого было достаточно, пока портативные устройства и управление питанием не стали играть более важную роль.

В Windows 8 была представлена новая модель приложений — приложения UWP. На высоком уровне было добавлено новое приостановленное состояние. Приложение UWP приостанавливается вскоре после того, как пользователь свернет его или переключится на другое приложение. Это означает, что потоки приложения будут остановлены, а приложение останется в памяти, если операционной системе не потребуется освободить ресурсы. Когда пользователь вернется к этому приложению, его работу можно будет быстро восстановить.

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

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

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

В Windows 10 версии 1607 представлены два дополнительных состояния модели приложения: Работает на переднем плане и Работает в фоновом режиме. Мы также рассмотрим эти новые состояния в следующих разделах.

Состояние выполнения приложения

На рисунке показаны возможные состояния модели приложений начиная с Windows 10 версии 1607. Изучим стандартный жизненный цикл приложения UWP.

Диаграмма состояния, показывающая переходы между состояниями приложения

Приложения переходят в фоновый режим при запуске или активации. Если приложению нужно перейти на передний план в связи с запуском приложения переднего плана, приложение получает событие LeavingBackground.

Хотя термины «запущен» и «активирован» кажутся похожими, они отражают различные способы запуска приложения операционной системой. Сначала рассмотрим запуск приложения.

Запуск приложения

При запуске приложения вызывается метод OnLaunched. Ему передается параметр LaunchActivatedEventArgs, который, помимо прочего, предоставляет аргументы, переданные приложению, идентификатор плитки, которая запустила приложение, и его предыдущее состояние.

Получить предыдущее состояние приложения можно с помощью функции LaunchActivatedEventArgs.PreviousExecutionState, которая возвращает объект ApplicationExecutionState. Далее описаны его значения и соответствующие действия.

ApplicationExecutionState Объяснение Предстоящее действие
NotRunning Приложение могло быть в этом состоянии, поскольку оно еще не запущено с момента последней перезагрузки или входа пользователя в систему. Кроме того, приложение может оказаться в этом состоянии, если оно работало, но затем было закрыто пользователем или в результате сбоя. Инициализировать приложение так, будто оно запускается в первый раз в сеансе текущего пользователя.
Suspended Пользователь свернул приложение или переключился на другую задачу и не вернулся в течение нескольких секунд. Если приложение было приостановлено, его состояние сохраняется в памяти. Вам нужно просто повторно получить все дескрипторы файлов или другие ресурсы, освобожденные, когда приложение было приостановлено.
Terminated Приложение было ранее приостановлено, но затем закрыто, поскольку системе потребовалась дополнительная память. Восстановить состояние, в котором приложение находилось, когда пользователь переключился на другую задачу.
ClosedByUser Пользователь закрыл приложение жестом в режиме планшета или с помощью сочетания клавиш ALT+F4. Когда пользователь закрывает приложение, оно сначала приостанавливается и затем завершает работу. Так как приложение, по сути, прошло те же этапы, которые ведут к состоянию Terminated, выполните такие же действия, как и для этого состояния.
Running Приложение было уже открыто, когда пользователь попытался запустить его снова. Отсутствует. Обратите внимание, что другой экземпляр приложения не запущен. Уже запущенный экземпляр просто активируется.

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

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

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

При запуске приложения Windows отображает его экран-заставку. Подробнее о настройке экрана-заставки см. в статье Добавление экрана-заставки.

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

После завершения запуска приложение переходит в состояние Running, и экран-заставка исчезает, а все соответствующие ресурсы и объекты удаляются.

Активация приложений

В отличие от запуска пользователем приложение может быть активировано системой. Приложение может быть активировано контрактом, например контрактом отправки данных. Кроме того, оно может быть активировано для обработки пользовательского протокола URI или файла с расширением, с которым связано ваше приложение. Перечень способов активации приложения см. в статье ActivationKind.

Класс Windows.UI.Xaml.Application определяет методы, которые можно переопределить для обработки различных типов активации приложения. Метод OnActivated используется для обработки всех возможных типов активации. Однако более часто используются другие методы обработки наиболее распространенных типов активации, и метод OnActivated используется как резервный для менее распространенных типов активации. Существуют другие методы для конкретных активаций:

OnCachedFileUpdaterActivated;
OnFileActivated;
OnFileOpenPickerActivated OnFileSavePickerActivated
OnSearchActivated;
OnShareTargetActivated.

Данные события для этих методов содержат то же свойство PreviousExecutionState, которое мы видели выше. Оно указывает, в каком состоянии находилось приложение перед активацией. Интерпретируйте состояние и определите ваши действия так же, как описано в разделе Запуск приложения.

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

Выполнение в фоновом режиме

Начиная с Windows 10 версии 1607 приложения могут выполнять фоновые задачи в том же процессе, в котором работает само приложение. Подробнее об этом см. в статье Модель фонового действия с одним процессом. В этой статье мы не рассматриваем фоновую обработку с одним процессом, но следует отметить, что в жизненный цикл приложения добавлены два новых события, связанные с фоновым выполнением приложения. Это события EnteredBackground и LeavingBackground.

Они также отражают, может ли пользователь видеть интерфейс приложения.

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

Выполнение на переднем плане

Пользовательский интерфейс приложения, которое выполняется на переднем плане, виден.

Событие LeavingBackground срабатывает непосредственно перед отображением пользовательского интерфейса и перед тем, как приложение переходит в состояние выполнения на переднем плане. Оно также активируется, когда пользователь возвращается к приложению.

Ранее лучшим местом для загрузки ресурсов интерфейса были обработчики событий Activated и Resuming. Теперь же обработчик события LeavingBackground — лучший способ проверить готовность вашего интерфейса.

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

Когда пользователь переключается на другую задачу, ваше приложение снова переходит в фоновое состояние.

Повторный переход в фоновое состояние

Событие EnteredBackground указывает, что приложение больше не отображается на переднем плане. На настольном компьютере событие EnteredBackground срабатывает, когда приложение свертывается, на телефоне — при переключении на начальный экран или другое приложение.

Уменьшение объема памяти, которое потребляет приложение

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

Если вы планируете выполнять какие-то задачи в фоновом режиме, здесь можно к этому подготовиться. Лучше всего проверить свойство MemoryManager.AppMemoryUsageLevel и, если требуется, уменьшить объем памяти, который использует ваше приложение, работающее в фоновом режиме, чтобы система не закрыла его, чтобы освободить ресурсы.

Дополнительные сведения см. в статье Уменьшение используемого объема памяти при переходе приложения в фоновое состояние.

Сохранение состояния

Обработчик события приостановки является лучшим местом для сохранения состояния приложения. Если вы выполняете какие-то задачи в фоновом режиме, такие как воспроизведение звука, с использованием расширенного сеанса выполнения или фоновую задачу, выполняемую внутри процесса, то лучше сохранить данные не синхронно с обработчиком событий EnteredBackground. Это связано с тем, что приложение может быть завершено, пока оно находится в фоновом режиме с более низким приоритетом. Поскольку в этом случае приложение не перейдет в приостановленное состояние, ваши данные будут потеряны.

Сохраните данные в обработчике событий EnteredBackground, прежде чем начнутся работы в фоновом режиме, чтобы повысить эффективность его возврата на передний план. Вы можете использовать API данных приложения для сохранения параметров и данных. Подробнее: Хранение и извлечение параметров и прочих данных приложения.

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

Помните, что если приложение выполняет фоновые задачи, оно может перейти из фонового состояния в состояние выполнения на переднем плане, минуя приостановленное состояние.

Асинхронные работа и отсрочки

Если вы используете асинхронный вызов в обработчике, контроль после его завершения возвращается немедленно. Это означает, что обработчик событий вернет управление приложению, которое сможет перейти в следующее состояние, даже если асинхронный вызов еще не завершен. Используйте метод GetDeferral объекта EnteredBackgroundEventArgs, который передается обработчику события, чтобы задержать приостановку после вызова метода Complete возвращенного объекта Windows.Foundation.Deferral.

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

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

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

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

Если приложение приостановлено, оно вызывает событие Application.Suspending. Шаблоны проектов UWP Visual Studio предоставляют обработчик этого события, OnSuspending, в файле App.xaml.cs. До Windows 10 версии 1607 код для сохранения состояния здесь размещался здесь. Теперь рекомендуется сохранять состояние при входе в фоновый режим, как описано выше.

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

Помните о крайнем сроке

Чтобы устройство работало быстро, на время, необходимое для выполнения кода в обработчике события приостановки, наложено ограничение. Для каждого устройства оно различное, и вы можете узнать его с помощью свойства Deadline объекта SuspendingOperation.

Как и в случае с EnteredBackground, если используется асинхронный вызов из обработчика, управление немедленно возвращается после его завершения. Это означает, что обработчик событий вернет управление приложению, которое сможет перейти в приостановленное состояние, даже если асинхронный вызов еще не завершен. Используйте метод GetDeferral объекта SuspendingOperation (доступного через аргументы события), чтобы отложить переход в приостановленное состояние до момента, когда будет вызван метод Complete возвращенного объекта SuspendingDeferral.

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

Завершение работы приложения

Система старается сохранить ваше приложение и его данные в памяти, пока его выполнение приостановлено. Тем не менее, если ресурсов системы для сохранения вашего приложения в памяти недостаточно, система завершает его работу. Приложения не получают уведомление о том, что они будут завершены, поэтому единственная возможность сохранить данные приложения — обработчик событий OnSuspension или асинхронный вызов из обработчика **EnteredBackground **.

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

Замечание об отладке с использованием Microsoft Visual Studio: с помощью Visual Studio можно предотвратить приостановку системой Windows работы программы, подключенной к отладчику. Это позволяет пользователю видеть пользовательский интерфейс отладчика Visual Studio во время выполнения приложения. При отладке программы с помощью Visual Studio вы можете отправить ей событие приостановки. Убедитесь, что отображается панель инструментов Место отладки, а затем щелкните значок Приостановить.

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

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

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

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

Если приостановленное приложение активировано для участия в контракте приложений или расширении, оно получает сначала событие Resuming, а затем— событие Activated.

Если работа приостановленное приложения была завершена, событие Resuming не срабатывает, а вызывается метод OnLaunched(), при этом параметру ApplicationExecutionState присвоено значение Terminated. Поскольку вы сохранили состояние во время приостановки приложения, вы можете восстановить его в методе OnLaunched (), чтобы приложение выглядело так же, как и до приостановки.

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

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

Общие рекомендации см. в руководстве по приостановке и возобновлению работы приложения.

Закрытие приложений

Обычно пользователям не нужно закрывать приложения. Они могут разрешить Windows управлять ими. Но пользователь может закрыть приложение с помощью соответствующего жеста, нажав клавиши ALT+F4 или воспользовавшись диспетчером задач в Windows Phone.

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

Поведение закрытия на уровне пользователей: Если ваше приложение должно сделать что-то еще при закрытии пользователем разному при закрытии пользователем и Windows, чтобы определить, является ли приложение вело пользователем или системой Windows можно использовать обработчик событий активации. Описания состояний ClosedByUser и Terminated приведены в справочных документах по перечислению ApplicationExecutionState.

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

Сбой приложения

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

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

Когда пользователь активирует приложение после сбоя, его обработчик событий активации получает параметр ApplicationExecutionState со значением NotRunning и должен просто отобразить его начальный пользовательский интерфейс и данные. После сбоя не используйте данные приложения, которые вы бы использовали для события Resuming из состояния Suspended, поскольку эти данные могут быть повреждены; см. раздел Рекомендации по приостановке и возобновлению приложений.

Удаление приложения

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

Жизненный цикл приложения и шаблоны проектов Visual Studio

Базовый код, который соответствует жизненному циклу приложения, содержится в шаблонах проектов Visual Studio. Базовое приложение обрабатывает активацию запуска, предоставляет место для восстановления данных приложения и отображает основной пользовательский интерфейс еще до того как, вы добавите собственный код. Дополнительные сведения см. в статье Шаблоны проектов на C#, VB и C++ для приложений.

Основные API жизненного цикла приложения