Опубликован: 12.02.2013 | Доступ: свободный | Студентов: 785 / 44 | Длительность: 17:51:00
Специальности: Программист
Лекция 9:

Использование системных функций в приложениях

Аннотация: Интерфейс приложений для Windows Phone основывается на концепции Metro-стиля, который включает концепцию "живых плиток". В телефоне может быть установлено множество приложений, но одновременно может работать только одно приложение. При этом, пользователь может переключаться между приложениями, и у него должно быть ощущение, что приложения работают параллельно. Приложения могут создавать фоновые задачи, а также использовать различные системные функции телефона, например, создавать сообщения SMS и электронной почты, использовать камеру, мультимедиа ресурсы библиотеки телефона и др. В этой лекции вы познакомитесь с особенностями создания Metro-приложений и особенностями их работы в Windows Phone.

Презентацию к данной лекции Вы можете скачать здесь.

22.1. Значки и экраны-заставки приложений для Windows Phone

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

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

Кроме этого, пользователь может "пролистать" экран меню Пуск влево (или нажать небольшую стрелку в верхнем правом углу экрана) и перейти к списку всех установленных в устройстве приложений. Этот список можно прокручивать вверх и вниз, и в нём также можно запустить программу. Если пользователь хочет, чтобы интересующее его приложение можно было запустить из главного экрана, он может "прикрепить" это приложение к экрану.

При создании нового проекта приложения Silverlight Visual Studio создаёт в проекте два файла со значками. В файле ApplicationIcon.png хранится изображение, которое используется в списке приложений. Изображение в файле Background.png используется, если приложение "прикреплено" к главному экрану. При создании приложений XNA Visual Studio создаёт такие же файлы, только вместо ApplicationIcon.png используется имя файла GameThumbnail.png.

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

Экран-заставка — это первый экран приложения, который выводится на экран Windows Phone при запуске приложения. Экран-заставка может содержать информацию о приложении, логотип и название компании и т.п. Пользователь видит экран-заставку приложения, пока оно загружается в память устройства.

Система Silverlight поддерживает использование экранов-заставок. При создании нового проекта Silverlight создаётся файл изображения, который отображается на экране с момента запуска приложения до тех пор, пока на экран не выведется страница MainPage. Если в программе используется много элементов и ресурсов, для загрузки приложения может понадобиться некоторое время. Для создания собственной экран-заставки нужно отредактировать файл SplashScreenImage.jpg в проекте Silverlight.

В отличие от Silverlight, ресурсы программы XNA не содержат экранов-заставок как таковых, поскольку программы XNA выполняются иначе. При запуске программы XNA вызывается метод LoadContent, который загружает все ресурсы игры, после чего вызываются методы Draw и Update, и использование экрана-заставки может привести к проблемам. Среда XNA ожидает, что приложение выведет на экран какое-нибудь изображение в течение пяти секунд после запуска программы. Если за это время ничего не выводится, выполнение приложения прерывается.

Однако, среда XNA не должна загружать сразу весь контент при запуске приложения. Игра может использовать контент-менеджер для загрузки ресурсов в любое время, и даже может выполнять фоновую загрузку ресурсов в несколько потоков. Таким образом, при создании приложения XNA необходимо разработать стратегию загрузки контента. Например, в методе LoadContent можно загружать только текстуру экран-заставки, которая может выводиться на экран в то время, как приложение будет загружать остальные элементы контента.

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

22.2. Быстрое переключение приложений

Устройства Windows Phone являются довольно мощными устройствами, однако, по сравнению с настольными системами их ресурсы несколько ограничены. Например, мощность процессоров телефонов ограничена ёмкостью аккумулятора, и хотя телефон может выполнять большой объём работы, лучше стараться сводить её к минимуму, чтобы продлить время автономного использования аккумулятора.

Операционная система Windows Phone, по сути, является многозадачной. Это означает, что одновременно в ней может выполняться несколько процессов. Например, телефон может воспроизводить музыку в программе Zune, и в это время можно проверить электронную почту. Однако, по многим техническим причинам такая многозадачность не распространяется на запущенные в системе приложения. Создатели системы Windows Phone приняли решение не позволять более чем одному приложению быть активным в любой момент времени.

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

В Windows Phone есть специальные средства для переключения между программами. Они основаны на использовании аппаратных кнопок Назад и Пуск, которые есть во всех устройствах Windows Phone.

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

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

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

В Windows Phone реализована концепция, которая получила название "быстрое переключение приложений". Поскольку неактивные программы обычно сохраняют своё состояние в оперативной памяти, переключение между ними выполняется довольно быстро.

В файле приложения Silverlight App.xaml.cs описаны методы, которые вызываются, когда происходят события, связанные с переключением приложений:

// Код для выполнения при запуске приложения (например, из меню "Пуск")
// Этот код не будет выполняться при повторной активации приложения
private void Application_Launching(object sender, LaunchingEventArgs e)
{
}

// Код для выполнения при активации приложения (переводится в основной режим)
// Этот код не будет выполняться при первом запуске приложения
private void Application_Activated(object sender, ActivatedEventArgs e)
{
}

// Код для выполнения при деактивации приложения (переводится в фоновый режим)
// Этот код не будет выполняться при закрытии приложения
private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
}

// Код для выполнения при закрытии приложения (например, при нажатии пользователем
// кнопки "Назад")
// Этот код не будет выполняться при деактивации приложения
private void Application_Closing(object sender, ClosingEventArgs e)
{
}

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

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

Запуск программы. Пользователь запускает установленную в телефоне программу. В процессе запуска программные файлы загружаются в память и обрабатываются процессором Windows Phone. При этом, вызывается метод Application_Launching, который загружает необходимые данные из изолированного хранилища. Однако, если требуется загрузить большой объём данных, лучше выполнять загрузку в отдельном потоке (то есть в фоновом режиме) — иначе приложение ничего не будет выводить на экран, пока этот метод не закончит работу.

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

Завершение работы программы при нажатии на кнопку Назад. В приложениях для Windows Phone нет кнопки Закрыть, которая закрывала бы приложение. Однако, приложение можно закрыть, если пользователь находится на главной странице приложения (то есть, на той странице, которая выводится на экран при запуске приложения) и нажмёт кнопку Назад. В этом случае оно выгружается из памяти, и происходит переход к открытому ранее приложению (если такое есть). Таким образом, пользователь может перейти к другому приложению и после завершения работы с ним вернуться к текущему приложению.

Как и приложения для настольных компьютеров, приложение Windows Phone может использовать событие, которое происходит при закрытии приложения, для сохранения открытых файлов. Соответствующий код нужно указать в методе Application_Closing. Также можно добавить вывод окна, в котором пользователь может подтвердить намерение закрыть приложение.

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

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

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

Выгрузка из памяти бездействующего приложения. При увеличении количества бездействующих приложений память телефона рано или поздно заканчивается. В этом случае некоторые приложения должны удаляться из памяти, чтобы освободить место для других приложений. В терминах Windows Phone приложение изменяет статус "бездействующее" (которое хранится в памяти и доступно для быстрого переключения приложений) на "выгруженное" (удалённое из памяти). Пользователь все ещё может возобновить выгруженное приложение, если достаточно много раз будет нажимать на кнопку Назад или выберет его из меню диспетчера запущенных приложений. При этом, для возобновления работы выгруженного приложения понадобится больше времени по сравнению с возобновлением работы бездействующего приложения.

При возобновлении работы выгруженной программы она будет заново загружаться в память и также заново создавать все её объекты, как если бы программа запускалась впервые. Однако, есть отличия в процессе возобновления выгруженной программы от запуска программы. Система Windows Phone предоставляет программе некоторый объём памяти для сохранения информации о состоянии приложения. В случае возобновления работы программы её можно загрузить обратно. Эта информация сохраняется, если приложение деактивировано, бездействует или выгружено.

Система Windows Phone также использует эту область памяти. Если деактивировать приложение, то при возврате к нему открывается та же самая страница приложения, которая была открыта перед деактивацией приложений. Система Silverlight использует хранилище состояния для сохранения в памяти активной страницы приложения при его деактивации.

Возобновление бездействующего или выгруженного приложения. При запуске приложения происходит событие Launching, а при возобновлении работы приложения — событие Activated. В последнем случае приложение может проверить, из какого состояния оно восстанавливается — из состояния "бездействует" или состояния "выгружено":

private void Application_Activated(object sender, ActivatedEventArgs e)
{

    if (e.IsApplicationInstancePreserved)
    {
        // восстановление из состояния "бездействует"
        // все объекты сохранены в памяти
    }
    else
    {
        // восстановление из состояния "выгружено"
        // требуется повторная загрузка объектов
    }
}

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

Добавление возможности быстрого переключения приложений

Рассмотрим, как приложение должно использовать возможность быстрого переключения приложений на примере приложения для создания текстовых заметок, которое было рассмотрено в лекции 5. Обновлённое приложение будет называться Журнал заметок (рис. 22.1). Оно позволит пользователю хранить последовательность записей в файле журнала. Каждая запись имеет "штамп времени", который добавляется при сохранении введённой записи и затем добавляется в журнал, который является длинной строкой текста. При запуске программы на экран выводится главная страница, на которой можно добавить запись. Пользователь может ввести текст в текстовое поле и нажать кнопку сохранить, чтобы добавить запись в журнал, или нажать кнопку журнал для перехода к другой странице программы, на которую выводятся сохранённые ранее записи.

Экран программы Журнал заметок

Рис. 22.1. Экран программы Журнал заметок

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

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

// эта переменная используется всеми страницами приложения
// она содержит текст всех заметок в виде длинной строки
public string LogText;

// эта переменная используется только на странице добавления новой заметки
public string LogEntry = "";  

Эти переменные лучше объявить в классе App, который объявлен в файле App.xaml.cs. Этот файл является "контейнером" для всего приложения, и в нём можно разместить данные, которые совместно используются всеми страницами приложения. Также этот класс содержит методы, которые используются для управления быстрым переключением приложений и позволяют сохранять и загружать данные о программе.

Перемещение между страницами приложения. В этом приложении будет две страницы, между которыми пользователь может перемещаться. Важно, чтобы страница всегда отображала правильные данные. Для этого можно использовать метод OnNavigatedTo:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
    // получение ссылки на активное приложение
    App thisApp = App.Current as App;  

    // вывод текста заметки на экран
    logTextBox.Text = thisApp.LogEntry;
}

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

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

protected override void OnNavigatedFrom(
    System.Windows.Navigation.NavigationEventArgs e)
{
    base.OnNavigatedFrom(e);

    // получение ссылки на активное приложение
    App thisApp = App.Current as App;

    // сохранение текста заметки в памяти приложения
    thisApp.LogEntry = logTextBox.Text;
}

Метод OnNavigatedFrom вызывает Silverlight при переходе пользователя на другую страницу. Метод копирует текст текстового поля в память приложения. Фактически, выполняются действия, обратные действиям метода OnNavigatedTo.

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

Сохранение данных при закрытии приложения. Если пользователь нажимает кнопку Назад, находясь на главной странице приложения, система Silverlight закроет приложение. При этом будут вызываться два метода:

  1. Метод OnNavigatedFrom страницы, на которой находится пользователь.
  2. Метод Application_Closing для сохранения данных приложения.

Метод OnNavigatedFrom копирует данные с текущей страницы в память приложения, а метод Application_Closing должен сохранять эти данные в изолированном хранилище.

private void Application_Closing(object sender, ClosingEventArgs e)
{
    SaveToIsolatedStorage();
}

Метод SaveToIsolatedStorage должен сохранять значения переменных logText и LogEntry в изолированном хранилище.

Загрузка данных при запуске приложения. Код для загрузки данных из изолированного хранилища при запуске приложения можно поместить в метод Application_Activated:

private void Application_Launching(object sender, LaunchingEventArgs e)
{
    LoadFromIsolatedStorage();
}

Метод LoadFromIsolatedStorage должен загружать данные из изолированного хранилища в переменные приложения.

После выполнения метода Application_Launching система Silverlight загружает страницу приложения и вызывает её метод OnNavigatedTo, который выведет на страницу необходимые данные.

Обработка нажатия кнопки Пуск. Если во время работы приложения пользователь нажмёт кнопку Пуск, приложение перейдёт в состояние "бездействует". При этом, последовательно вызываются методы OnNavigatedFrom и Application_Deactivated. В последний метод можно добавить код для сохранения данных приложения.

private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
    SaveToIsolatedStorage();
    SaveToStateObject();
}

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

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

  • приложение активируется из состояния "бездействует". В этом случае все данные программы остаются в памяти, и их не нужно восстанавливать;
  • приложение активируется из состояния "выгружено". В этом случае программа должна заново загрузить все данные. При этом, можно использовать данные, сохранённые в хранилище состояния при деактивации приложения.

Эти действия выполняет следующий метод:

private void Application_Activated(object sender, ActivatedEventArgs e)
{
    if (!e.IsApplicationInstancePreserved)
    {
        // восстановление всех объектов приложения,
        // поскольку оно активировано из состояния "выгружено"
        LoadFromStateObject();
    }
}

Если приложение активировано из состояния "выгружено", то флаг IsApplicationInstancePreserved будет иметь значение true, а если из состояния "бездействует" — значение false.

Сохранение состояния. Программа может использовать изолированное хранение для хранения информации о её состоянии, даже если оно бездействует. Однако, для сохранения небольших объёмов данных этот способ является довольно громоздким. Для этого в Windows Phone можно использовать хранилище состояния. Разные программы используют разные хранилища состояния, и эти хранилища недоступны другим программам. Хранилище состояния сохраняет данные, даже если приложение находится в состоянии "выгружено".

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

private void Application_Deactivated(object sender, DeactivatedEventArgs e)
{
    SaveToIsolatedStorage();
    SaveToStateObject();
}

Этот метод вызывается, когда приложение переходит в состояния "выгружено". Метод SaveToStateObject описывается в файле App.xaml.cs и сохраняет состояние программы в памяти, используя вспомогательный метод для сохранения в хранилище состояния одной строки:

private void SaveToStateObject()
{
    SaveTextToStateObject("Log", LogText);
    SaveTextToStateObject("Entry", LogEntry);
}

Метод SaveTextToStateObject принимает два параметра: имя сохраняемого элемента и его значение:

private void SaveTextToStateObject(string filename, string text)
{
    IDictionary<string, object> stateStore = PhoneApplicationService.Current.State;

    stateStore.Remove(filename);

    stateStore.Add(filename, text);
}

Хранилище состояния представляет собой словарь объектов, который хранится в PhoneApplicationService.Current.State. Чтобы получить доступ к этому словарю, в программу нужно добавить ссылку на пространство имён Microsoft.Phone.Shell. Вся работа с хранилищем данных выполняется точно так же, как и с любым словарём.

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

private bool LoadTextFromStateObject(string filename, out string result)
{
    IDictionary<string, object> stateStore = PhoneApplicationService.Current.State;

    result = "";

    if (!stateStore.ContainsKey(filename))
        return false;

    result = (string)stateStore[filename];

    return true;
}

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

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

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

Использование быстрого переключения приложений при разработке приложения

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

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

В Visual Studio можно указать, что программа должна выгружаться из памяти при переходе в состояние "бездействует". Для этого в свойствах проекта на вкладке Отладка нужно поставить галочку в пункте Отметить как удаленный в результате деактивации во время. Эту возможность удобно использовать при тестировании программы и использовании быстрого переключения приложений.

Игра XNA также может обрабатывать события приостановки и деактивации приложения. Таким образом, игры могут сохранять состояние и рекорды, когда пользователь переключается к другому приложению.