Хотел бы попродробнее рассказать вам про одно из самых интересных на мой взгляд нововведений недавно прошедшей конференции Build 2014. Речь пойдет про одновременную разработку приложений для Windows 8 и Windows Phone, т.е. про универсальные приложения для платформы Windows.
Увеличить
Платформа Майкрософт покрывает широкий спектр устройств — от смартфонов и планшетов до настольных компьютеров и игровой приставки Xbox One, и вполне естественно, что разработчику хочется минимизировать усилия при создании приложений под все форм-факторы. На конкурирующих платформах существует огромная разница между настольными и мобильными приложениями (поскольку они работают под управлением различных операционных систем), при этом мобильные приложения, разработанные для смартфона, могут работать на планшетных устройствах, что зачастую приводит к неудовлетворенности пользователя из-за не очень качественного пользовательского интерфейса.
На данный момент Майкрософт вплотную подошел к тому, чтобы унифицировать все платформы (Windows Phone, Windows 8, Xbox One) с точки зрения API, и позволить программисту максимально использовать общий код при создании приложений, при этом сохранив возможность использования различного дизайна для различных форм-факторов. Подробнее про то, как это реализовано на текущий момент — читайте ниже.
Как раньше создавались приложения Windows + Phone
До сегодняшнего дня для создания приложений с общим кодом для Windows и Windows Phone приходилось использовать разделяемую переносимую библиотеку (portable library) для выделения общего кода, отвечающего за доступ к данным и бизнес-логику, и различные проекты для UI. Подробнее такой подход описан в специальном курсе на Microsoft Virtual Academy. Также из-за разницы в API Windows 8 и Windows Phone приходилось часть кода делать платформенно-зависимым.
Универсальные приложения Windows
На конференции build были объявлены следующие нововведения:
- В новой версии Windows Phone 8.1 будут использоваться Windows RT API. Это означает, что около 90% системных вызовов между Windows 8.1 и Windows Phone 8.1 будут общими. Кроме того, язык разметки XAML также был унифицирован между платформами. Иными словами, новые приложения Windows Phone 8.1 будут использовать Windows XAML, а не Silverlight. Если вам нужна совместимость, для Windows Phone по-прежнему можно будет разрабатывать с использованием Silverlight, в т.ч. используя новые возможности, но это тема для отдельной статьи.
- В Visual Studio 2013 Update 2 появится новый шаблон проекта для унифицированных приложений Windows. Этот шаблон создает различные проекты для Windows и Phone, и третий «разделяемый» проект, в котором размещается весь общий код. При этом разделяемый проект может содержать не только код, но и XAML-разметку, общие ресурсы, изображения и т.д. Этот проект не компилируется в отдельную библиотеку, а разделяется между двумя платформенными проектами на уровне текстового включения на этапе компиляции. Такой шаблон можно использовать для разработки на C#/XAML, C++/XAML или HTML/JS.
- Если вы хотите выделить часть платформенно-независимого кода в отдельную библиотеку, разделяемую между несколькими приложениями, то по-прежнему можно использовать переносимую библиотеку, в которую теперь можно включать также и XAML-разметку. Переносимые библиотеки можно использовать для разработки на C# или Visual Basic.
- Бинарной совместимости между платформами пока нет, т.е. приложения Windows 8 и Windows Phone по-прежнему будут распространяться через соответствующие магазины, и разработчику будет необходимо создать и загрузить в каждый из магазинов пакеты приложения (хотя теперь Windows Phone 8.1 будет использовать такой же формат .appx, что и Windows 8. Однако в магазинах Windows и Windows Phone будут использоваться единые идентификаторы приложений, что позволит реализовать сценарии единой покупки приложения для использования на всех платформах.
- Приложения для Xbox One в текущей версии Visual Studio Update 2 не так хорошо вписываются в общую историю, хотя на пленарном докладе было показано универсальное приложение Khan Academy с использованием Kinect, работающее на Xbox и Windows (да, Kinect v2 будет поддерживаться в приложениях магазина Windows, но это опять же тема для отдельной статьи). Разработка для Xbox One на текущий момент предполагается на HTML/JS/CSS и C++.
Таким образом, теперь появилась удобная возможность для разработчиков создавать приложения под платформы Windows и Windows Phone, которые содержат значительное количество общего кода, с возможностью кастомизировать дизайн под разные платформы для максимизации удовлетворенности пользоваталя!
Universal Hello World
Рассмотрим небольшой пример создания универсального приложения. Структура проектов в Visual Studio 2013 Update 2 была изменена, и теперь в разделе Магазин Window доступны как приложения для Windows и Windows Phone, так и универсальные приложения и библиотеки.
Увеличить
Вновь создаваемое универсальное приложение будет расчитано на платформу Windows Phone 8.1 и Windows 8.1 Update. При этом в разделе приложений Windows Phone доступны шаблоны проектов Windows Phone, основанные на Silverlight, которые позволят создавать приложения для ранних версий платформы — но возможности универсальных приложений при этом использовать нельзя.
После создания пустого универсального приложения, мы получим следующую структуру, состоящую из трех проектов: по одному проекту на каждую платформу и общий разделяемый проект:
Обратите внимание:
- По умолчанию дизайн страничек (XAML) для платформ разнесен по разным проектам. Однако в простых случаях вы можете использовать общие XAML-файлы для всех платформ, если вы уверены, что ваш дизайн будет достаточно хорошо адаптироваться к разным разрешениям, от смартфона до десктопа. При этом многие встроенные элементы управления (например, GridView) умеют адаптироваться и изменять свой внешний вид в зависимости от платформы.
- Если у вас есть уже готовый проект Windows или Windows Phone, вы можете создать на его основе универсальное приложение, выбрав в контекстном меню проекта соответствующий пункт. При этом проект будет преобразован в такую же трех-проектную структуру, и вы сможете переносить файлы приложения в общий проект для их совместного использования.
- В разреляемый проект можно включать ссылки на библиотеки (References), при этом эти ссылки будут добавлены в оба проекта (мы видим, что в ссылках каждого из платформенных проектов присутствует Shared-ссылка). Если какие-то библиотеки доступны только для одной из платформ, то мы все равно можем использовать соответствующую функциональность в общем коде, окружая её директивами условной компиляции #ifdef. Visual Studio настолько удобна, что при этом будет работать Intellisense, предупреждая нас о том, что ссылка доступна только в одной из платформ.
- Если мы выносим XAML-код в общий проект, то в редакторе XAML доступен drop-down для переключения платформы, и мы можем визуально редактировать дизайн страницы как в режиме телефона, так и в режиме планшета/десктопа.
Увеличить
В большинстве случаев вы захотите разделять как можно больше кода между платформами, перенеся все, что возможно, в проект shared. В нашем случае мы можем перенести MainPage.xaml из одного из проектов в разделяемый проект, и удалить его в платформенных проектах, поскольку в нашем случае дизайн странички не будет отличаться от платформы к платформе:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Style="{StaticResource HeaderTextBlockStyle}" HorizontalAlignment="Center" VerticalAlignment="Center">
Hello, world!
</TextBlock>
</Grid>
Таким образом, мы получили универсальное приложение, код и дизайн которого полностью находятся в разделяемом проекте.
На пути к реальному приложению — Photo Viewer
Попробуем превратить наше приложение Hello World во что-то полезное — например, в просмотрщик лучших фотографий flickr. Flickr предоставляет RSS-поток фотографий, поэтому определить соответствующий источник данных сравнительно просто (для пущей простоты загрузка RSS сделана не-асинхронной, в реальных проектах так делать не надо):
public class Flickr
{
List<BitmapImage> list = new List<BitmapImage>();
public Flickr()
{
var xdoc = XDocument.Load("http://api.flickr.com/services/feeds/photos_public.gne");
XNamespace xn = "http://www.w3.org/2005/Atom";
var res = from z in xdoc.Descendants(xn + "entry")
let l =
(from x in z.Descendants(xn + "link")
where x.Attribute("rel").Value == "enclosure"
select x.Attribute("href").Value).FirstOrDefault()
where (l!=null) && (l!="")
select l;
foreach (var x in res)
{
list.Add(new BitmapImage(new Uri(x)));
}
}
public List<BitmapImage> Images
{
get
{
return list;
}
}
На основной страничке используем GridView, привязанный к этому источнику данных. Для того, чтобы на разных платформах фотографии были разного размера, используем ключ из ресурсного файла, определяющий требуемый размер фотографии.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<GridView ItemsSource="{Binding Images}">
<GridView.DataContext>
<local:Flickr/>
</GridView.DataContext>
<GridView.ItemTemplate>
<DataTemplate>
<Image Height="{StaticResource ImageSize}" Width="{StaticResource ImageSize}" Source="{Binding}"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
Чтобы задать разные параметры в ресурсном файле, создадим в каждом из платформенных проектов свой ресурсный файл Resource.xaml следующего содержания:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UniversalHello">
<x:Double x:Key="ImageSize">150</x:Double>
</ResourceDictionary>
И в завершение нам надо подключить этот ресурсный файл в App.xaml (который находится в разделяемом проекте):
<Application ...>
<Application.Resources>
<ResourceDictionary Source="Resources.xaml"/>
</Application.Resources>
</Application>
В результате мы получаем пару приложений для Windows 8 и Windows Phone, которые корректно отображают галерею изображений с учетом специфики платформы.
Увеличить
Полный исходный код приложения можно получить на github.
Мораль
Для создания новых приложений на платформе Windows 8 сейчас лучшим решением будет использовать универсальные приложения. Если у вас есть существующее приложение Windows 8, то его имеет смысл потихоньку конвертировать в универсальное приложение и портировать на Windows Phone 8.1. Существующее приложения Windows Phone 8 преобразовать в универсальное приложение сложнее (т.к. для ряда операций используются другие наборы API), об этом мы еще с вами поговорим. Наконец, универсальные приложения для Windows Phone требуют версии Windows Phone 8.1, поэтому на текущий момент, чтобы иметь достаточно широкую install base, имеет смысл использовать приложения Silvelight 8.0.
Материалы
Доклады build по теме:
Скачать Visual Studio 2013 Update 2 RC