Основы разработки приложений для мобильных устройств на платформе Windows Phone

Фоновая обработка

Показывать лекцию целиком

Основные теоретические сведения

Многозадачность и фоновые сервисы

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

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

Фоновые задачи, запускаемые по расписанию

Можно создавать два типа задач: периодические (PeriodicTask) и ресурсоёмкие (ResourceIntensiveTask). Периодические задачи запускаются регулярно на небольшое время, ресурсоёмкие — запускаются на относительно длительное время, но только если выполнятся определённые условия, относящиеся к состоянию телефона. Классы для создания фоновых задач доступны в пространстве имён Microsoft.Phone.Scheduler.

Есть определенные ограничения, связанные в целом с задачами, запускаемыми по расписанию, и с каждым типом задач в отдельности:

  • приложение может иметь только одну фоновую задачу, запускающуюся по расписанию, но она может быть зарегистрирована и как периодическая, и как ресурсоёмкая;
  • не все функции устройства доступны в фоновых задачах;
  • фоновую задачу необходимо инициализировать в активном приложении, и она будет сохраняться между перезагрузками телефона;
  • у пользователя есть возможность управлять работой фоновых задач в настройках телефона;
  • максимальное время работы фоновой задачи — 14 дней (после этого можно инициализировать заново);
  • если агент завершит свою работу два раза подряд из-за превышения ограничений на память или из-за необработанного исключения, он будет удалён из расписания запуска;
  • количество фоновых задач на устройстве ограничено и зависит от конфигурации устройства.
  • Ниже приведена сравнительная таблица ограничений на периодические и ресурсоёмкие задачи.

    Периодические задачи Ресурсоёмкие задачи
    Интервал запуска Обычно, 30 минут, но в зависимости от состояния телефона (батарейка, запущенные процессы) может сдвигаться +/- 10 минут

    Телефон подключён к внешнему источнику питания

    Доступ в сеть не через сотовую связь

    Заряд батареи не менее 90%

    Нет активного звонка

    Телефон заблокирован

    Время работы Порядка 25 секунд Порядка 10 минут
    Ресурсы Меньше 6 Мб памяти, меньше 10% ресурсов процессора Меньше 6 Мб памяти

    Создайте новое приложение из шаблона Приложение Windows Phone, назовём его BackgroundAgentExample. Добавьте к решению новый проект Агент запланированных заданий Windows Phone и назовите его ToastAgent.

    Перейдите к проекту ToastAgent, двойным щелчком перейдите к редактированию файла ScheduledAgent.cs и добавьте следующий код в метод OnInvoke, который вызывается при запуске сервиса:

    using Microsoft.Phone.Shell; 
    
    ...
    
    protected override void OnInvoke(ScheduledTask task)
    {
        ShellToast toast = new ShellToast();
        toast.Title = "Toast Agent";
        toast.Content = "Сообщение от фонового сервиса";
        toast.Show();
    
    #if DEBUG
        ScheduledActionService.LaunchForTest(task.Name, System.TimeSpan.FromSeconds(10));
    #endif
    
        NotifyComplete();
    }
    

    Обратите внимание на код внутри директив условной компиляции. Он позволяет не ждать 30 минут запуска сервиса, а запустить его через 10 секунд после его последнего запуска.

    В основном проекте добавьте ссылку на проект ToastAgent.

    Перейдём к редактированию кода MainPage.xaml. Добавим кнопку, чтобы запустить наш периодический сервис и добавим обработчик события Click:

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
      <Button Content="Запустить сервис" Height="150" Name="StartAgent" Click="StartAgent_Click" />
    </Grid>
    

    Добавим в блок using директиву:

    using Microsoft.Phone.Scheduler;
    

    и определим константу с именем сервиса в классе MainPage:

    const string ToastAgentName = "Agent-Toast";
    

    Отредактируем обработчик события нажатия кнопки так, чтобы запускался сервис ToastAgent.

    private void StartAgent_Click(object sender, RoutedEventArgs e)
    {
    PeriodicTask myPeriodicTask = ScheduledActionService.Find(ToastAgentName) as PeriodicTask;
    
    if (myPeriodicTask != null)
    {
        try
        {
            ScheduledActionService.Remove(ToastAgentName);
        }
        catch (Exception ex)
        {
            MessageBox.Show("Невозможно удалить ранее созданный сервис:" + ex.Message);
        }
    }
    
    myPeriodicTask = new PeriodicTask(ToastAgentName);
    myPeriodicTask.Description = "Agent-Toast";
    
    try
    {
        ScheduledActionService.Add(myPeriodicTask);
    
    #if DEBUG
        ScheduledActionService.LaunchForTest(ToastAgentName, TimeSpan.FromSeconds(10));
    #endif
    }
    catch (Exception ex)
    {
        MessageBox.Show("Невозможно создать сервис:" + ex.Message);
    }
    

    Поле описание сервиса является обязательным, без него не удастся добавить сервис.

    Обратите внимание, что и здесь присутствует код, который в случае отладки вызывает сервис через 10 секунд.

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

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

    Фоновая загрузка/выгрузка файлов

    Для фоновой загрузки/выгрузки файлов предназначены классы в пространстве имён Microsoft.Phone.BackgroundTransfer.

    Файлы можно загружать/выгружать из/в изолированное хранилище приложения, при этом процесс будет продолжаться, даже если приложение не запущено. Если приложение запущено, но оно может отлеживать состояние и отображать его статус фоновой загрузки файлов. Пока поддерживаются GET/POST HTTP/HTTPS запросы для скачивания файлов и POST HTTP/HTTPS запросы для загрузки файла на сервер.

    Также существуют ограничения на размеры файлов, которые можно скачать/загрузить на сервер. На сервер можно загрузить файл не больше 5 Мб, скачать файл размером до 20 Мб можно по сотовой связи, файлы размером до 100 Мб – по беспроводной (Wi-Fi) (если нет подключения к источнику питания).

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

    Пример программного кода для фоновой загрузки и сохранения в изолированном хранилище файла RSS:

    string fileName = "..."; // имя скачиваемого файла
    
    string filePath = "..."; // адрес файла в Интернете
    
    Uri transferUri = new Uri(filePath);
     
    BackgroundTransferRequest transferRequest = new
        BackgroundTransferRequest(transferUri);
                    
    transferRequest.Method = "GET";                
     
    Uri downloadUri = new Uri("shared/transfers/" + fileName,
        UriKind.RelativeOrAbsolute);
    transferRequest.DownloadLocation = downloadUri;
     
    transferRequest.TransferStatusChanged += new
        EventHandler<BackgroundTransferEventArgs>(transferRequest_TransferStatusChanged);
     
    try
    {
        BackgroundTransferService.Add(transferRequest);
    }
    catch (Exception ex)
    {
                    
        MessageBox.Show("Невозможно запустить фоновую загрузку:" + ex.Message);
    }

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

    void transferRequest_TransferStatusChanged(object sender,
        BackgroundTransferEventArgs e)
    {
        //если скачивание прошло успешно, удаляем запрос на загрузку
        if (e.Request.TransferStatus == TransferStatus.Completed)
        {
            try
            {
                BackgroundTransferService.Remove(e.Request);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Невозможно удалить завершённую фоновую загрузку:" +
                    ex.Message);
            }
        }
    }
    
    

    Фоновое проигрывание музыки

    Также существуют классы для проигрывания локальной и потоковой музыки. Они находятся в пространстве имён Microsoft.Phone.BackgroundAudio. Создание приложений, которые используют эту возможность аналогично созданию приложений для фоновых сервисов, запускаемых по расписанию, с поправкой на специфику проигрывания аудио.

    В поставке средств разработки находятся два шаблона проектов Агент воспроизведения звука Windows Phone и Агент потоковой передачи звука Windows Phone для создания сервисов фонового проигрывания локальной и потоковой музыки соответственно. Особенностью данных сервисов является их тесная интеграция с платформой Windows Phone.

    Дополнительные материалы

    Сайт MSDN: http://msdn.microsoft.com/ru-ru/library/hh202961.

    Сайт MSDN: http://msdn.microsoft.com/ru-ru/library/hh394039.

    Задание к работе

  • Откройте в Visual Studio созданный в одной из предыдущих работ проект программы для Windows Phone или создайте новый проект.
  • Добавьте необходимый код для создания какой-либо периодической или ресурсоёмкой задачи (например, периодического добавления в файл информации о доступности подключения к Интернету).
  • Запустите программу и проверьте правильность её работы.
  • Составьте отчёт о проделанной работе. Включите в отчёт необходимые листинги программы.
  • Вернуться к учебному плану