Опубликован: 22.12.2012 | Доступ: свободный | Студентов: 415 / 14 | Длительность: 07:20:00

Лекция 6: Архитектура приложения для Windows Store. Понятие архитектуры. Архитектура WinRT. Требования

< Лекция 5 || Лекция 6 || Лекция 7 >
Аннотация: Лекция знакомит с особенностями WinRT. Приводится описание контрактов. Подробно рассматривается share contract.

WinRT была создана для предоставления единообразного (в то же время изменчивого с течением времени в плане новых веяний) и безопасного окружения для работы Windows-приложений. WinRT испытала на себе влияние .NET, C++ и JavaScript. Однако стоит учитывать, что WinRT не заменяет собой CLR или Win32, а предоставляет унифицированную среду выполнения приложений, написанных на разных языках, для запуска в новых версиях Windows с использованием интерфейса. Для разработки на WinRT можно использовать языки платформы .NET (C#, VB.NET, F#) и HTML/JavaScript/CSS

Архитектура WinRT

Рис. 5.1. Архитектура WinRT

По сути своей WinRT это новый набор API, основные особенности которого:

  • Обеcпечение пользовательского интерфейса
  • Упрощенное программирование GUI
  • WPF и XAML для построения интерфейсов

Все API-вызовы асинхронны. API изначально разработана как "песочница" (приложения сразу готовы к размещению в WindowsStore). Определения API-вызовов представлены в формате метаданных ECMA 335 (лежат в файлах .winmd)

WinRT призвано уменьшить степень взаимовлияния приложений - производительность одного приложения не должно влиять на производительность другого; ресурсы и объекты одного приложения доступны другим только через стандартные каналы ОС (контракты).

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

Вот некоторые из типов контрактов:

  • Search - благодаря этому контракту приложение может стать источником поиска данных. Поиск внутри вашего приложения появляется на панели инструментов операционной системы, но данным контрактом могут воспользоваться и другие приложения;
  • Sharing - с помощью этого контракта можно открыть доступ к данным других приложений. Выше был описан пример интеграции приложения с социальными сетями;
  • Play To - этот контракт предназначен для передачи медиаданных из приложения на внешние устройства;
  • Settings - данный контракт предоставляет доступ к настройкам приложения, благодаря чему система может интегрировать все настройки в свою панель инструментов;
  • App to App - благодаря этому типу контрактов приложения могут не только обмениваться данными, но и предоставлять доступ к различных хранилищам, которыми оперируют.
  • Picker - описывается какими данными приложение хочет поделится с другими, что делает простым доступ к файлам этого приложения извне, унифицируя интерфейс доступа к виду как будто бы происходит работа с жестким диском.

Рассмотрим механизм работы контрактов. Для примера возьмем контракт share ("Отправка") состоящий из двух частей share source и share target. Приложение, которое хочет чем-то поделится с другим приложением реализует свою часть контракта (share source), принимающее - свою (share target) при этом приложениям ничего не нужно знать друг о друге, а только позаботится об исполнении своей части "контракта", об остальном (прием/передача информации и унифицированность процесса) позаботится ОС.

Share Contract

Очень важно помнить, что данная функциональность работает только для WinRT-приложений и недоступна на традиционном рабочем столе.

Для передачи через share contract можно использовать

  • простой текст
  • URI
  • HTML
  • отформатированный текст
  • изображение
  • файл
  • данные в формате представленном разработчиком

Пример с расшариванием текста:

// подключаем пространство имен, которое необходимо для базового шаринга
using Windows.ApplicationModel.DataTranfer;
/*в случае если нужно больше используются
Windows.Storage - для объекта StorageFile (передача файлов)
Windows.Storage.Pickers для открытия диалога выбора файлов/изображений
Windows.Storage.Streams часто используется при передаче файлов/изображений/данных в 
собственном формате Windows.Graphics.Imaging используется для изменения изобраежений
перед расшариванием (создание превью, уменьшение размеров, поворот на угол, увеличение и т.п.)
*/

Чтобы сообщить ОС что приложение собирается что-то расшарить в функции OnNavigatedTo следует сделать следующее

// зарегестрируем приложение как источник шары
this.dataTransferManager = DataTransferManager.GetForCurrentView();
this.dataTransferManager.DataRequested += new TypedEventHandler<DataTransferManager, 
DataRequestedEventArgs>(this.OnDataRequested);

В коде выше dataTransferManger это поле класса выбранной страницы типа DataTransferManager, а OnDataRequested - callback-функция для обработки запроса на расшаривание.

Функция вызывается при нажатии на charm Sharing. Содержимое функции OnDataRequsted

private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs e)
{
  string dataPackageTitle = TitleInputBox.Text;
if (!String.IsNullOrEmpty(dataPackageTitle))
  {
    string dataPackageText = TextToShare.Text;
    if (!String.IsNullOrEmpty(dataPackageText))
    {
      DataPackage requestData = e.Request.Data;
      requestData.Properties.Title = dataPackageTitle; 
        string dataPackageDescription = DescriptionInputBox.Text;
      if (dataPackageDescription != null)
      {
        requestData.Properties.Description = dataPackageDescription;
      }
      requestData.SetText(dataPackageText);
    }
    else
    {
      // Нечем делиться
    }
  }
  else
  {
// Нет обязательного заголовка пакета
  }
}

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

  1. Сообщить операционной системе, что приложение поддерживает контракт sharing;
  2. Заполнить служебную информацию о DataPackage (заголовок (обязательно), описание (желательно);
  3. Заполнить и отправитьданные через SetText, SetUri etc для стандартных вариантов и через SetData (будет рассмотренно ниже) для своего формата данных.

Рассмотрим отдельно расшаривание файлов, чтобы описать контракт FilePicker и расшаривание данных своего формата для того, чтобы полностью закончить описания шаринга в Windows 8.

При расшаривании файлов порядок действий тот же с одним исключением - пользователю нужно выбрать, какие файлы он хочет передать другому приложению (этот случай используется здесь только для демонстрации FilePicker'a в Windows 8 имеется возможность программно инициировать шаринг)

Сначала нужно объявить переменную в которй будет хранится список файлов (1 или более)

private IReadOnlyList<StorageFile> storegeItems; 

Затем в качестве callback-функции для события Clicked для какой-либо кнопки, например с надписью "Выбрать файлы" реализовать следующее:

FileOpenPicker filePicker = new FileOpenPicker 
  {
      ViewMode = PickerViewMode.List,
      SuggestedStartLocation = PickerLocationId.DocumentsLibrary,
      FileTypeFilter = { "*" }
  };

  IReadOnlyList<StorageFile> pickedFiles = await filePicker.PickMultipleFilesAsync();

  if (pickedFiles.Count > 0)
  {
      this.storegeItems = pickedFiles;
  }

Все, теперь можно подготавливать пакет данных, складывать в него файлы и отправлять:

private void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs e)
{
  string dataPackageTitle = "shared file exapmle";
    string dataPackageDescription = "Here we will transfer some file(s) to another app";

    DataPackage req = e.Request.Data;
    req.Properties.Title = dataPackageTitle;
    req.Properties.Description = dataPackageDescription;
    req.SetStorageItems(this.storegeItems);
}

Расшаривание данных собственного формата. Например это информация о книге в формате json

string DataPackageFormat = "book-info";
       string DataPackageText =
       @"{
          ""type"" : ""http://schema.org/Book"",
          ""properties"" :
          {
           ""image"" : ""http://sourceurl.com/catcher-in-the-rye-book-cover.jpg"",
           ""name"" : ""The Catcher in the Rye"",
           ""bookFormat"" : ""http://schema.org/Paperback"",
           ""author"" : ""http://sourceurl.com/author/jd_salinger.html"",
           ""numberOfPages"" : 224,
           ""publisher"" : ""Little, Brown, and Company"",
           ""datePublished"" : ""1991-05-01"",
           ""inLanguage"" : ""English"",
           ""isbn"" : ""0316769487""
           }
       }"; 

А теперь отправим эти данные

if (!String.IsNullOrEmpty(dataPackageText))
   {
       DataPackage requestData = e.Request.Data;
       requestData.Properties.Title = dataPackageTitle;

       // The description is optional.
       string dataPackageDescription = DescriptionInputBox.Text;
       if (dataPackageDescription != null)
       {
           requestData.Properties.Description = dataPackageDescription;
       }
       requestData.SetData(dataPackageFormat, dataPackageText);
   }

Как видно из кода единственная разница между своим форматом данных и стандартными заключается в одной единственной строчке:

requestData.SetData(dataPackageFormat, dataPackageText); 

А теперь рассмотрим вторую часть контракта - сторона принимающего приложения. Сначала в манифесте приложения необходимо указать, что оно выступает в качества share target (реализует эту часть контракта), затем в настройках этого объявления указать какие типы данных и файлов оно может принимать.

Манифест приложения

увеличить изображение
Рис. 5.2. Манифест приложения

Затем в функцию OnNavigatedTo следует добавить код вроде этого

this.shareOperation = (ShareOperation)e.Parameter;
 var unused = Task.Factory.StartNew(async () =>
 {
   // Получим свойства пакета данных
   this.sharedDataTitle = this.shareOperation.Data.Properties.Title;
   this.sharedDataDescription = this.shareOperation.Data.Properties.Description;
   this.sharedThumbnailStreamRef = this.shareOperation.Data.Properties.Thumbnail;
   this.shareQuickLinkId = this.shareOperation.QuickLinkId;

   // а теперь непосредственно данные
   // проверяем, что именно мы получили и обрабатываем
   If(this.shareOperation.Data.Contains(StandardDataFormats.Text))
   {
             try
             {
                 this.sharedText = await this.shareOperation.Data.GetTextAsync();
             }
             catch (Exception ex)
             {
             } 
   }
   // И так далее для всех зарегестрированных типов данных
   // однако не стоит забывать про this.shareOperation.Report*()
   // где * -это Started, DataRecieved, Completed для сообщения ОС этапов отработки контракта. 

Подробная информация о классе Page (именно его методы OnNavigatedTo, OnNavigatedFromи OnDataRecievedбыли рассмотрены).

Прием и передачи файла

Рис. 5.3. Прием и передачи файла

Краткие итоги

В лекции на конкретных примерах рассмотрены особенности архитектуры WinRT. Приведены свойства и назначение основных компонентов WinRT.

Вопросы

  1. Каковы особенности WinRT?
  2. Что такое контракты?
  3. Для чего используется контракт ShareBroker?
  4. Для чего используется контракт Picker?
  5. Для чего используется контракт Search?
  6. Для чего используется share contract?
  7. Приведите примеры расшаривания.

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

< Лекция 5 || Лекция 6 || Лекция 7 >
Максим Иванов
Максим Иванов
а, ВЭГУ
Василий Вячин
Василий Вячин
Россия, Москва, НПО Информ-Система, Специалист-разработчик