Просто и понятно о Xamarin: как разработать кроссплатформенное мобильное приложение. Пошаговая инструкция
Xamarin — это опенсорс-фреймворк для разработки кроссплатформенных мобильных приложений с использованием библиотек .NET.
Чаще всего в качестве среды разработки выбирают Microsoft Visual Studio, а в качестве языка — C#. Такое сочетание позволяет компилировать, собирать и запускать один и тот же код (общий код) для:
- iOS (.ipa — iOS App Store Package);
- Android (.apk — Android Package Kit);
- Windows (UWP — Universal Windows Platform).
В большинстве случаев созданные таким образом приложения будут работать и выглядеть на каждой из платформ как нативные (родные).
Xamarin — это не только инструмент, это некий подход к процессу разработки. Он позволяет писать большую часть общего кода на одном языке и использовать его в других проектах.
Преимущества Xamarin
- Выше я уже упомянул про общий код. Так вот, доля этого кроссплатформенного кода может достигать 80% или даже 90%. Понятно, что чудес не бывает и все зависит от специфики вашего приложения. Если, например, вы пишете хардкорный код для обработки аудио/видео в реальном времени, он будет платформо-зависимым, и доля общего кода снизится. Но если вы ограничиваетесь написанием бизнес-логики — тогда ситуация обратная.
- Xamarin позволяет напрямую достучаться до нативного API каждой из трех упомянутых платформ. То есть на нем можно писать и платформо-зависимый код.
- Так как это опенсорс-фреймворк, свой вклад в его разработку может вносить сообщество (что оно и делает). Благодаря энтузиастам появляются сторонние компоненты, а также расширяется список платформ и библиотек, которые могут поддерживать Xamarin-приложения. Так список пополнился операционными системами MacOS и Tizen, а также UI-библиотеками для WPF и GTK#.
- Одно из спорных преимуществ Xamarin — это тесная связь с C# и .NET. Поклонники этого языка и экосистемы .NET в целом будут считать это преимуществом, а скептики найдут, к чему придраться.
Лицензия и другие условия использования
Есть две новости — хорошая и плохая. Начнем с плохой.
Стоит предупредить, что сейчас, без машины с MacOS компилировать, собирать и отлаживать Xamarin-приложения под iOS (официально) нельзя. Возможно, ограничение получится обойти, но насколько это легально?
Теперь хорошая новость: Xamarin распространяется бесплатно — в том числе и для коммерческого использования.
Документация и сторонние компоненты
У Xamarin довольно обширная документация. Она охватывает общие вопросы разработки кроссплатформенных приложений. Много внимания уделено библиотеке Xamarin.Forms. Кроме того, существуют отдельные большие блоки документации по специфическим вопросам разработки для Android и iOS.
На английском языке:
На русском:
Экосистема дожила до того счастливого момента, когда для Xamarin начали пилить сторонние компоненты. Среди популярных переиспользуемых компонентов и шаблонов пользовательского интерфейса, можно выделить:
Поддержка системных требований (для Windows и для Mac)
Платформа | macOS
(Visual Studio для Mac) |
Windows
(Visual Studio) |
Xamarin.iOS | Да | Да (с компьютером Mac) |
Xamarin.Android | Да | Да |
Xamarin.Forms | iOS и Android | Android, классические приложения Windows и UWP (iOS с компьютером Mac) |
Xamarin.Mac | Да | Только открыть проект и компилировать |
Xamarin.Mac 4.8 будет работать на macOS версии 10.9 (Mavericks) и выше.
Xamarin для Visual Studio будет работать на Visual Studio 2019 и Visual Studio 2017 (Community, Professional и Enterprise). Чтобы использовать новейшие версии SDK для Android и iOS нужна обновленная версия Visual Studio. Если хотите разрабатывать на Xamarin под UWP, вам понадобится Windows 10.
Я выбрал Windows с Visual Studio 2019 Community. Далее все примеры будут относиться именно к этой конфигурации. А собирать и запускать Xamarin-приложение я буду под Android OS.
Установка Xamarin в Visual Studio
1. Для Visual Studio 2019 и 2017 процесс очень похож. Это касается и Community (бесплатной версии), и Professional, и Enterprise. Возможно, какая-то из этих версий VS у вас уже установлена (она не должна быть старше 2017, но это не эйджизм). Если нет — скачать можно здесь.
2. В обоих случаях нужно начать с запуска инсталлятора (Visual Studio Installer). Его можно найти на своем компьютере, например, через меню Пуск. Если вы только скачали VS без установки, просто запустите скачанный файл.
3. Выберите рабочую нагрузку (вкладка Workloads) под названием Mobile development with .NET.
4. Больше ничего не надо выбирать. Оставьте в покое настройку Install while downloading в списке вариантов установки и нажмите Install или Change (если VS уже была установлена).
5. Дождитесь окончания установки.
6. Проверьте, что выбранные вами компоненты установлены. Для этого запустите Visual Studio, в главном меню выберите пункт Help и далее — About Microsoft Visual Studio:
Все прошло успешно!
Как работает Xamarin?
Xamarin построен на базе Mono. Это опенсорс-реализация спецификации CLI (Common Language Infrastructure) с виртуальной машиной и компилятором C#.
В рамках разработки Mono также реализовано множество библиотек, совместимых с .NET Framework, а также расширяющих его функциональность.
Xamarin включает две ключевых библиотеки для разработки приложений для мобильных платформ — Xamarin.Android и Xamarin.iOS (их названия говорят сами за себя).
Дело в том, что код Xamarin-приложения (напоминаю: это код на C#) не может напрямую обращаться к нативному API операционной системы Android или iOS. Проблему решают эти библиотеки, которые преобразуют код в соответствующие нативные вызовы.
Xamarin.Android использует пространства имен Android* и Java* из виртуальной среды выполнения Android Runtime (ART). Обращаться к ним позволяет специальный набор оберток Managed Callable Wrappers (MCW), который и выполняет необходимые преобразования с C#-кодом. Обратные преобразования выполняются через другой набор классов — Android Callable Wrappers (ACW).
Xamarin.iOS занимается статической (AOT — Ahead-Of-Time) компиляцией C#-кода в нативный ARM-код. В отличие от Just-In-Time (JIT) компиляции Xamarin.Android, происходяще в процессе работы приложения, исходный код заранее преобразуется в исполняемый (в данном случае — в ассемблерный код для мобильного процессора с архитектурой ARM). Параллельно работает среда выполнения Objective C. С помощью промежуточного слоя под названием Bindings Xamarin.iOS обеспечивает преобразование вызовов C# API в вызовы Objective C и обратно (выполняет те же задачи, что и MCW / ACW в Xamarin.Android).
На более высоком уровне абстракции находятся библиотеки Xamarin.Essentials и Xamarin.Forms, которые предоставляют кроссплатформенный API. Например, Xamarin.Forms позволяет создать единый кроссплатформенный UI (допустим, с помощью XAML), повесить на него обработчики и реализовать эту обработку (с помощью C#). Этот код можно запустить на всех трех платформах, о которых мы тут говорим.
Xamarin.Essentials — это библиотека, предоставляющая кросс-платформенный API (обертку) для единообразного использования нативных функций (геолокация, блокировка экрана или показания датчиков устройства).
Xamarin.Forms — это библиотека для разработки UI с помощью комбинации XAML и C#. Созданные таким образом абстрактные элементы управления могут быть преобразованы в нативные контролы соответствующей платформы. В данном случае это преобразование называется рендерингом.
Кроме того, Xamarin.Forms может похвастаться такими фичами, как Databinding, Gestures, Effects и Styling.
Структура проекта и разработка UI
Выше мы уже решили, что в этой статье вся практика будет опираться на конфигурация Windows с Visual Studio 2019 Community. Поэтому продолжаем с ней же.
Здесь мы рассмотрим шаблон проекта Mobile App (Xamarin Forms), потому что Xamarin в первую очередь ассоциируется с кроссплатформенной разработкой.
Mobile App (Xamarin Forms)
Будем разбираться на практике. Для начала создадим свой проект (а точнее — Solution или «решение»):
Уже понятно, какой тип проекта нужно выбрать:
Назовем его HelloHighloadToday:
Далее выбираем набор платформ, для которых будем создавать Solution. Я не стал устанавливать инструменты разработки UWP-приложений, поэтому этот пункт у меня не активен.
А работая на MacOS в Visual Studio для Mac, вы обнаружите, что этого пункта просто не будет. Вот такое платформенное ограничение: видимо, UWP там не в почете.
Я также выбрал пункт Blank (пустой), чтобы в сгенерированном коде не было ничего лишнего. Так проще с ним разбираться.
Все, Solution создан! Посмотрим на его структуру:
Так как я выбрал две платформы, то дополнительно к основному проекту (HelloHighloadToday) VS создала еще два (платформо-зависимых):
- HelloHighloadToday.Android;
- HelloHighloadToday.iOS.
По умолчанию жирным выделен проект HelloHighloadToday.Android, но важно понимать, что основным проектом остается HelloHighloadToday. Без этого проекта невозможно заставить один и тот же код работать на остальных двух.
Hello, HighloadToday: как работает код
Теперь разберемся, как работает сгенерированный код.
Посмотрим на структуру основного проекта — HelloHighloadToday. Здесь нас интересуют пять файлов: App.xaml, App.xaml.cs, MainPage.xaml, MainPage.xaml.cs и AssemblyInfo.cs.
AssemblyInfo.cs хранит настройки компиляции для Xamarin-приложения. Об этом файле — пока все.
Файлы App.xaml и App.xaml.cs
Есть более интересные файлы App.xaml и App.xaml.cs. Они отвечают за запуск приложения (для любителей английского: App — Application). Файл App.xaml — первая стартовая точка приложения.
По его расширению можно догадаться, что код внутри написан на XAML (язык разметки на основе XML). Этот декларативный язык обычно используется для описания пользовательского интерфейса или ресурсов. В этом файле обычно описываются глобальные ресурсы (например, стили), которые можно использовать внутри всего приложения. Нам тут пока описывать нечего, но в качестве примера можно посмотреть на такое:
<Application.Resources> <Style TargetType="Grid"> <Setter Property="Background" Value="Red" /> </Style> </Application.Resources>
С описанием UI мы встретимся чуть позже.
App.xaml работает в паре с файлом App.xaml.cs. Это вторая стартовая точка.
В этом файле создается пользовательский класс App — наследник класса Application (Приложение). Полное название этого класса определяется в файле App.xaml. В нашем случае это:
x:Class = "HelloHighloadToday.App"
В конструкторе этого класса есть важный вызов метода InitializeComponent()
, который отвечает за начальную инициализацию объекта нашего класса App, производного от класса Application. Там же, в конструкторе, устанавливается наша главная страница приложения (MainPage, о ней пойдет речь далее).
Кроме того, в этом же классе Visual Studio заботливо сгенерировала пустые обработчики основных событий для типичного мобильного приложения — OnStart()
, onSleep()
и onResume()
. Писать внутри свой код или не писать — целиком и полностью решаем мы с вами (то есть разработчики, которые используют Xamarin). Тут же можно подписаться и на другие события.
Файлы MainPage.xaml и MainPage.xaml.cs
Эта пара файлов состоит примерно в таких же отношениях, как App.xaml и App.xaml.cs:
x:Class = "HelloHighloadToday.MainPage"
Только в MainPage.xaml описан пользовательский интерфейс. По аналогии с HTML, здесь элементы UI представлены в виде тегов (с своими индивидуальными атрибутами) и вложены в некий контейнер StackLayout (хотя возможны разные уровни вложенности и варианты контейнеров), который, в свою очередь, вложен в страницу нашего приложения ContentPage:
Код внутри обоих файлов был автоматически сгенерирован во время создания проекта:
Видно, что код в этом файле еще проще, чем в App.xaml.cs. Здесь важно, что класс MainPage является наследником класса главной страницы ContentPage.
Выглядит сгенерированное приложение вот так:
Разработка UI
Для разработки визуального интерфейса кроссплатформенных приложений используют Xamarin.Forms. UI мобильных Xamarin-приложений состоит из одной или нескольких страниц.
Наш проект пока содержит только одну страницу — MainPage. Она была добавлена автоматически при создании проекта. Мы можем и сами добавлять новые страницы.
Добавление страниц на базе готовых шаблонов
Шаблоны подразделяются по типам страниц. Но для нас сейчас важнее заметить, что некоторые шаблоны не позволяют создать для страницы XAML-файл.
Например, при создании страницы на базе шаблона ContentPage будут созданы два файла — Page1.xaml и Page1.xaml.cs. В случае с шаблоном ContentPage (C#) будет создан только файл Page1.cs.
Из этого вытекают два подхода к разработке UI.
UI на C#
Это код, сгенерированный при создании страницы на базе шаблона ContentPage (C#).
UI с XAML
Это XAML-код, сгенерированный при создании страницы на базе шаблона ContentPage.
Это cs-код, сгенерированный при создании страницы на базе шаблона ContentPage.
Здесь файл .xaml с описанием UI отделен от .cs-файла. Тогда имеет смысл договориться, что во втором файле будем писать только логику взаимодействия с визуальным интерфейсом. Такой подход считается более рациональным: c декларативным стилем XAML структура UI выглядит более наглядно, код проще понимать и поддерживать, благодаря разделению над каждым из двух файлов может работать отдельный специалист. И это явно реверанс в сторону любителей HTML.
В обоих случаях нужно вносить изменения в код ручками, потому что у Xamarin.Forms нет Дизайнера (Конструктора форм). Но если создать Solution вроде Android App (Xamarin), то там Дизайнер присутствует. Только это уже тема для другой статьи.
Хорошо, так давайте же внесем эти изменения!
Делаем свой UI с XAML и обработкой событий
Усложним сгенерированный пример. Сформулируем ТЗ на наше Xamarin-приложение HelloHighloadToday:
1. Показать приветственный экран. Он должен содержать:
- заголовок («Знакомься с Xamarin!»);
- развернутый призыв к действию в следующем блоке текста;
- кнопку с надписью https://highload.tech/category/teoriya;
- кнопку с надписью CLEAR;
- невидимый WebView.
2. По нажатию кнопки с надписью https://highload.tech/category/teoriya обеспечить показ страницы по указанной ссылке: WebView должен стать видимым.
3. По нажатию кнопки с надписью CLEAR обеспечить возврат приложения к состоянию 1 (то есть спрятать WebView).
Я не буду рассказывать про сами элементы UI в расчете на то, что вы с ними знакомы или быстро сможете познакомиться.
Перепишем сначала файл MainPage.xaml. Я, не сильно раздумывая, выбрал терпимый вариант размещения элементов визуального интерфейса. Вы можете сделать по-своему:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloHighloadToday.MainPage"> <StackLayout> <StackLayout> <Frame BackgroundColor="#2196F3" CornerRadius="0"> <Label Text="Знакомься c Xamarin!" HorizontalTextAlignment="Center" TextColor="White" FontSize="26"/> </Frame> <Label Text="Пиши свой код! Начни с проекта HelloHighloadToday. Читай эту и другие статьи в разделе «Теория»" FontSize="16" Padding="30,14,30,0"/> <StackLayout Padding="30,14,30,14"> <Button x:Name="LoadWebPageButton" Text="https://highload.tech/category/teoriya/" TextColor="White" BackgroundColor="#2196F3" Clicked="OnLoadWebPageButtonClicked"></Button> <Button x:Name="HideWebPageButton" Text="Clear" TextColor="White" BackgroundColor="#2196F3" Clicked="OnHideButtonClicked"></Button> </StackLayout> </StackLayout> <WebView x:Name="WebView1" VerticalOptions="FillAndExpand" /> </StackLayout> </ContentPage>
Теперь обработаем нажатия на кнопки:
Вот такая нехитрая логика.
Запуск под Android
Давайте проверим, действительно ли наш код из основного проекта будет работать на Android OS без танцев с бубном. Проверять будем на настоящем смартфоне с установленной операционной системой 10-й версии. Система не самая новая, поэтому будет еще интереснее посмотреть, взлетит ли на ней проект.
На приведенном выше скриншоте видно, что наш основной (кроссплатформенный) проект подключен как reference, а точнее — библиотека динамической компоновки (файл HelloHighloadToday.dll). Это один из ключевых нюансов реализации кроссплатформенности. DLL-библиотека активно используется для работы Xamarin-приложения на Android OS.
А сейчас просто посмотрим на код файла MainActivity.cs (это главный и единственный экран) из нашего проекта HelloHighloadToday.Android. Он также написан на C# — ни слова про Java, как видите.
Отмечу, что этот код полностью сгенерирован Visual Studio. В нем подключаются и используются все необходимые пространства имен и библиотеки для работы с Android (в том числе — Xamarin.Forms и Xamarin.Essentials, описанные выше). Кроме того, MainActivity.cs использует настройки и ресурсы основного проекта (HelloHighloadToday). Ну и, конечно же, в методе OnCreate(Bundle savedInstanceState)
выполняется инициализация и старт приложения.
using System; using Android.App; using Android.Content.PM; using Android.Runtime; using Android.OS;
В этом коде я не менял ничего.
Отлаживать приложение можно и в эмуляторе. Но для этого ваша машина должна поддерживать виртуализацию и работать достаточно шустро.
Посмотреть список виртуальных устройств или добавить новое можно через Tools -> Android -> Android Device Manager.
Если вы, так же, как я, запускаете приложения на реальном устройстве, то нужно выполнить несколько простых манипуляций с вашим смартфоном (или что там у вас c Android OS):
1. Подключить устройство к компьютеру по USB.
2. Зайти в Настройки -> О телефоне и щелкнуть по Номеру сборки 7 раз.
3. Зайти в Настройки -> Система и обновления и выбрать пункт Для разработчиков:
4. Включить сначала опцию Разрешить отладку по ADB только при зарядке, а потом опцию Отладка по USB. Первая опция вроде бы не обязательна, но без нее у меня не работало:
5. И еще один шаг на всякий случай. Если Visual Studio не может найти ваше устройство после всех предыдущих шагов — выполните Tools -> Android -> Restart Adb Server:
6. Проверьте, чтобы указанные в настройках пути вели, куда надо. Иначе Visual Studio просто не найдет нужные версии SDK и JDK.
7. Чтобы успешно скомпилировать приложение, нужно выбрать версию ОС, которая установлена на вашем устройстве (или виртуальном устройстве, если используете эмулятор).
8. Для запуска приложения на устройстве номер версии Android OS не должен быть меньше указанного в настройках манифеста (Minimum Android version):
Попробуйте подключить старый Andorid, и увидите, что будет (спойлер: ничего не будет!).
Вернемся к нашему проекту
Нам остается только запустить Xamarin-приложение на устройстве Android. Сборка произойдет автоматически:
Смотрите-ка, запустилось:
Нажав на кнопку с надписью https://highload.tech/category/teoriya, получим:
Действительно появляется WebView с соответствующим контентом.
Нажав на кнопку с надписью CLEAR, возвращаемся к первому экрану.
Отлично, все работает в соответствии с нашим ТЗ и даже не падает, когда я закрываю приложение, смахивая его с дисплея моего смартфона.
Публикация приложения
Чтобы загрузить приложение в Google Play, нужно иметь соответствующий аккаунт и выполнить целый ряд требований. Описание этого процесса выходит за рамки моего рассказа и превышает всякие объемы приличия. Уж простите. Если сильно нужно, то с этой статьи можно начать квест (там и для iOS, и для Android OS). Но сейчас не переключайтесь, пожалуйста.
Потому что здесь я расскажу, как правильно скомпилировать проект для публикации, как создать ключ, подписать и собрать готовый к публикации .apk-файл.
В Visual Studio на панели инструментов под главным меню выбираем Release вместо Debug:
В Solution Explorer выбираем Android-проект, нажимаем правую кнопку мыши и открываем его свойства (левой кнопкой на Properties):
Далее переходим в Android.Manifest. Тут почти ничего менять не пришлось (как минимум это справедливо для Visual Studio Community 2019 16.11.0). Понадобилось только выбрать иконку приложения (Application icon). Эту иконку (точнее набор копий иконки разных размеров) Xamarin выдает по умолчанию. Можно заменить на свою в папке Resources текущего проекта:
На следующей вкладке Android.Options убираем галочку с опции Enable developer instrumentation (debugging and profiling). Так безопаснее. Сегодня спонсор паранойи — корпорация Microsoft:
Сохраняем и закрываем окно со свойствами и опять попадаем в Solution Explorer. Там последовательно выполняем два действия:
1. Очищаем проект (Clean ).
2. Пересобираем проект (Rebuild).
Выбираем Android-проект, нажимаем правую кнопку мыши и затем — Archive.
Дожидаемся, пока сформируется файл .apk. Сформировался? Замечательно. Но пока он не подписан. Поэтому продолжаем.
Нажмем на кнопку Distribute:
В появившемся окне выберем Ad Hoc (мы ведь создаем apk без загрузки в Google Play):
Далее нужно создать Ключ (Android Key Store), которым будем подписывать наш файл приложения:
Ниже пример заполнения полей. Нужно заполнить все поля и нажать Create.
Важно: запомните пароль, который вы придумали, так как через пару-тройку шагов вновь потребуется его ввести!
После создания Ключа нужно нажать Save As для сохранения подписанной версии файла .apk:
Здесь можно ввести произвольное название для файла:
При сохранении потребуется ввести пароль, который мы вбили при создании Android Key Store.
Все, мы получили .apk-файл, который можно скопировать на телефон или разослать кому-то по почте. Пишите письма. Пока!
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: