Xamarin как запустить приложение на телефоне
Итак, в прошлых темах мы создали первый проект, теперь запустим его на ОС Android. Так как главный проект компилируется в библиотеку dll, то нам надо запустить собственно тот проект, который предназначен для этой операционной системы. То есть в данном случае HelloApp.Android .
Если рабочая машина, на которой ведется разработка, поддерживает виртуализацию, то мы можем для отладки приложений использовать эмуляторы: эмулятор Android от Microsoft или Android Player.
Если у нас есть устройство с ОС Android, то мы можем его использовать для тестирования. Для этого надо подключить это устройство к компьютеру с помощью USB-кабеля. А на самом мобильном устройстве установить режим разработчика в параметрах.
Вполне возможно, что мобильное устройство подключено к компьютеру, должным образом настроено, но Visual Studio его все равно не видит. В этом случае можно перезугрузить сервер Adb. Для этого надо в Visual Studio перейти в меню к пункту Tools -> Android -> Restart Adb Server :

Перед самим запуском можно настроить некоторые параметры, которые связаны с Android. Так, если мы перейдем в Visual Studio в меню Tools -> Options и в появившемся окне выберем пункт Xamarin -> Android Settings . Здесь мы можем настроить расположение Java SE SDK и Android SDK, а также настройки эмулятора и прочее.

Далее мы можем перейти в свойства проекта для Android, и в настройках установить версию среды Android, которая будет использоваться для компиляции приложения:

Следует учитывать, что последняя версия Xamarin Forms не поддерживает версии ниже Android 10 в качестве целевой версии Android.
Важную роль играют настройки манифеста, где мы можем установить различные разрешения, иконку и название приложения, целевую и минимальную версию Android, которые будут поддерживаться приложением, и прочие настройки:

Версию среды стоит учитывать, если у нас определенное мобильное устройство, которое мы хотим использовать для тестирования. Если его версия Android ниже минимальной, то Visual Studio может просто не увидеть это устройство, даже если оно подключено через USB к компьютеру.
Если же все настроено правильно, то в панели инструментов Visual Studio отобразит подключенное устройство:

В моем случае это устройство Nexus 5X. Попутно в списке могут отображаться и другие подключенные устройства и эмуляторы.
Если необходимо установить какую-то новую версию Android API или какие-то компоненты из Android SDK, можно перейти к меню Tools -> Android -> Android SDK Manager и там отметить нужные компоненты для установки.
И в конце мы можем запустить проект. В соответствии с имеющимся кодом он будет отображать метку с текстом в центре экрана:

Стоит отметить, что в процессе развертывания приложения на устройстве Xamarin устанавливает ряд пакетов Xamarin Android API-xx Support , что можно увидеть через окно вывода Output в Visual Studio или на смартфоне в диспетчере приложений:
Name already in use
xamarin-android / Documentation / workflow / DevelopmentTips.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Development tips and native debugging
Tips and tricks while developing Xamarin.Android.
Run MSBuild-Based On-Device Unit Tests
The tests/MSBuildDeviceIntegration directory contains NUnit-based unit tests which need to run against an attached Android device (hardware or emulator). There are lots of tests in here, and running them all can take a significant amount of time.
If you need to run only one [Test] method, you can use dotnet test —filter :
When a Xamarin.Android app launches on an Android device, and the app was built in the Debug configuration, it will create an «update» directory during process startup, printing the created directory to adb logcat :
When the app needs to resolve native libraries and assemblies, it will look for those files within the update directory first. This includes the Mono runtime library and BCL assemblies.
Note that the update directory is per-app. The above mentioned Mono.Android_Tests directory is created when running the Mono.Android-Tests.csproj unit tests.
The update directory is not used in Release configuration builds. (Note: Release configuration for the app itself, not for xamarin-android.)
Keep in mind that only the app that owns the update directory has permission to write to it, so on a normal non-rooted device or emulator, you’ll need to use adb shell run-as to add new files. For example, if you’re working on a mono/x86 bug and need to quickly update the app on the device to test libmonosgen-2.0.so changes:
Alternatively, if you’re working on an mscorlib.dll bug:
On some devices, the run-as command might not have permission to read the files in /data/local/tmp/ . In that case, you can use a cat command that pipes to the run-as command:
Attaching LLDB using mono/lldb-binaries on macOS
Download the precompiled lldb and lldb-server binaries from https://github.com/mono/lldb-binaries/releases, and follow the instructions within README.md.
If you need to run the app with managed debugger attached, first edit the xa-lldb script to comment out the following line:
Then start the app from Visual Studio with managed debugging as usual. After that, run the xa-lldb script as described in README.md.
Adding debug symbols for libmonosgen-2.0.so
First, you’ll need to get a version of libmonosgen-2.0.so that includes debug symbols. You can either use a custom local build or download the debug version of libmonosgen-2.0.so for a published Xamarin.Android version:
Go to https://github.com/xamarin/xamarin-android/tags and click on the Xamarin.Android version you are debugging.
Find the OSS core section at the bottom of the release information and click the link to the open-source build.
Navigate to Azure Artifacts in the left sidebar and download the xamarin-android/xamarin-android/bin/Release/bundle*.7z file. For the d16-2 branch and earlier, the file extension will be .zip instead of .7z .
Extract the libmonosgen-2.0.d.so files from the bundle. For example, if you have brew installed, run:
On Windows, Visual Studio includes the 7z.exe executable when the Mobile development with .NET workload is installed, so you can use that:
For d16-2 and earlier, use unzip instead:
(On Windows, the Git Bash command prompt includes the unzip command, so that’s one way to complete this step.)
Next, there are a few options to get LLDB to see the debug symbols.
Option A: Add the library with symbols as an @(AndroidNativeLibrary)
This option is convenient because it doesn’t require any adb commands. On the other hand, it requires rebuilding and redeploying the app to test each version of libmonosgen-2.0.so , so it’s not ideal if you need to test several different versions of libmonosgen-2.0.so .
Ensure that Android Options > Use Shared Runtime is enabled.
Add the appropriate architecture of libmonosgen-2.0.d.so to the corresponding lib subdirectory of the app project as described in the Using Native Libraries documentation. For example, if debugging an arm64-v8a app, add the arm64-v8a version of libmonosgen-2.0.d.so to the project in lib/arm64-v8a/ .
Rename the file to libmonosgen-2.0.so .

Set the Build Action of the file to AndroidNativeLibrary.

Build, deploy, and run the app. Then attach LLDB.
If desired, follow the image lookup and settings set — target.source-map steps from the Debugging Mono binaries with LLDB guide to allow stepping through the Mono runtime source files.
Option B: Upload the library with symbols to the update directory
This option is useful for testing a number of different libmonosgen-2.0.so versions quickly without rebuilding or redeploying the app, but it requires a little care to complete the adb steps correctly on the command line.
Push the appropriate architecture of libmonosgen-2.0.d.so into the application’s update directory and rename it to libmonosgen-2.0.so :
Ensure all users have execute permissions on the application’s data directory:
This will allow LLDB to re-download libmonosgen-2.0.so and load the symbols from it.
Run the app and attach LLDB.
Option C: Manually load the library with symbols
This option allows testing an existing debuggable APK without pushing anything new to the device. The other options are usually more convenient, but loading the symbols by hand might be useful in some cases.
After attaching LLDB to the app, add the appropriate architecture of libmonosgen-2.0.d.so into LLDB with a command like:
Find the current in-memory address of the .text section of libmonosgen-2.0 . For example, for a 64-bit app that’s using the shared runtime, run the following command:
Look for the row of the table that shows «code» as the «Type»:
Load the .text section from libmonosgen-2.0.d.so at the in-memory starting memory address of the .text section:
Attaching GDB using Visual Studio on Windows
Visual Studio can attach GDB to Xamarin.Android for native debugging. The integration includes the usual features like the graphical thread and call stack windows and the ability to set breakpoints using the source code editor.
In the Visual Studio Installer, under the Individual components tab, ensure that Development activities > C++ Android development tools is installed.
Install the Android NDK if you don’t already have it. For example, use Tools > Android > Android SDK Manager to install it.
Set Tools > Options > Cross Platform > C++ > Android > Android NDK to the Android NDK path. For example:
Quit and relaunch Visual Studio.
Use File > Open > Project/Solution to open the signed debuggable APK for the application.
Set the Build > Configuration Manager > Active solution platform to the application ABI. If debugging an arm64-v8a application, explicitly add a platform named ARM64 and set it as the active platform.
If you need symbols for libmonosgen-2.0 , copy the library file with symbols to a convenient local location, making sure the file name matches the name on device (for example, libmonosgen-64bit-2.0.so if using the 64-bit shared runtime), and add the local location of the library to Project > Properties > Additional Symbol Search Paths.
Start the app, for example by launching it with or without managed debugging from Visual Studio, or by tapping the app on the device.
Select Debug > Attach to Android process and wait for the connection to complete.
If needed, you can use Debug > Windows > Immediate to interact with the GDB command line. Prefix GDB commands with -exec to get the expected behavior. For example to view the stack backtrace:
You can set GDB to continue through the various native signals that Mono uses for its normal internal operations by running the following command in the Immediate window:
Attaching LLDB using Android Studio on Windows or macOS
The LLDB integration in Android Studio is quite similar to the GDB integration in Visual Studio. This is a useful option if you are debugging on Windows and are more familiar with LLDB than GDB or if you already have Android Studio installed and don’t currently have the Android NDK installed.
Install Android Studio. If you already have an Android SDK installation for Xamarin.Android, you can click Cancel on the Android Studio Setup Wizard when you launch Android Studio.
Open the signed debuggable APK for the application in Android Studio via Profile or debug APK on the start window or the File > Profile or Debug APK menu item.

If you skipped the Android Studio Setup Wizard, navigate to File > Project Structure > Modules > Mono.Android_Tests-Signed > Dependencies, click New > Android SDK next to the Module SDK.

Select the Android SDK folder you’re using with Xamarin.Android, and then under Build target, pick the appropriate Android API to match the APK.

Wait for the Indexing status message at the bottom of the Android Studio window to disappear.
Start the app, for example by launching it with or without managed debugging from Visual Studio, or by tapping the app on the device.
In Android Studio, select Run > Attach Debugger to Android Process, or click the corresponding toolbar icon.

Set the Debugger to Native, select the running app, and click OK.
If the adb connection is slow, the first connection to the app will take a while to download all the system libraries. The connection might time out if this takes too long, but the next connection attempt will have fewer libraries left to download and will likely succeed.
You can set LLDB to continue through the various native signals that Mono uses for its normal internal operations by opening View > Tool Windows > Debug, selecting the Android Native Debugger tab, navigating to the inner Debugger [tab] > LLDB [tab] command prompt, and running the following process handle command:

Attaching GDB on the command line on Windows or macOS
If the automated methods to attach LLDB or GDB are hitting errors or getting stuck, you can try to attach GDB from the command line as a fallback. These steps rely on having the Android NDK installed.
Push the appropriate architecture of gdbserver to the device for the app you are debugging. For example, if debugging an arm64-v8a app:
Ensure all users have execute permissions on the application’s data directory:
Start the app, for example by launching it with or without managed debugging from Visual Studio, or by tapping the app on the device.
Find the process ID of the running app, for example by using adb shell ps :
Start gdbserver , attaching it to the running app process:
In another console window, use adb to forward the debug_socket UNIX domain socket to a TCP port on the local host:
Pull the appropriate app_process* file for the application to a local location. For example, if debugging an arm64-v8a app:
If you need symbols for libmonosgen-2.0 , copy the library file with symbols to the same local location, making sure the file name matches the name on device (for example, libmonosgen-64bit-2.0.so if using the 64-bit shared runtime).
Run the following commands in GDB to set up the debugger and attach it to the app:
Finding Mono runtime packs
The Mono «runtime packs» for Android are:
main builds of the Mono runtime packs are on the following NuGet feed, such as this nuget.config :
You can view these packages on Azure DevOps here:
You can search for a given pack such as Microsoft.NETCore.App.Runtime.android-arm and download the .nupkg for a given version if needed.
To find the commit of a given package, locate the .nuspec file inside the .nupkg , and look for:
This information is also visible on Windows if you have NuGet Package Explorer.
Testing different Mono runtime pack versions
One common scenario that comes up — how does one test a specific dotnet/runtime build along with a .NET 6 Android application?
One way to do this would be to copy individual files on top of the NuGet cache, such as:
However, this is not the best idea, since there are many files in these packs. It would be an OK approach if you only need to update one file.
A second (better) way is to add this MSBuild target to your Android .csproj file:
6.0.0-preview.7.21364.3 is a version from the dotnet6 feed above, and so you would also need an accompanying nuget.config file.
This could also be used with local or CI builds of dotnet/runtime by copying .nupkg files to the library-packs directory of a given .NET install:
- C:\Program Files\dotnet\library-packs
- /usr/local/share/dotnet/library-packs
- bin/$(Configuration)/dotnet/library-packs
The library-packs directory is simply an implicit NuGet feed that is automatically picked up by the .NET SDK.
Enabling Mono Logging
Since 6e58ce4, logging from Mono is no longer enabled by default. You can set the debug.mono.log system property to answer questions like: Is AOT working? Is the Mono Interpreter enabled?
If you wanted to enable logging for AOT, for example:
You could use mono_log_mask=all to enable all logging. See the Mono documentation for more information about MONO_LOG_LEVEL and MONO_LOG_MASK . You can specify more than one category as the value of mono_log-mask , in which case individual categories need to be separated with : , for instance:
There is further logging produced by libmonodroid.so you can enable with:
You can combine both together. The following would log nearly everything:
To unset debug.mono.log , you can do:
You could also reboot the device or emulator to completely clear all system properties.
The debug.mono.log system property can also be set in an @(AndroidEnvironment) text file. However, the system property will be preferred if it is not blank.
Installing .NET MAUI
make pack-dotnet or msbuild Xamarin.Android.sln -t:PackDotNet provisions a .NET SDK and locally built Android workload in:
If you also want .NET MAUI, you don’t want to dotnet workload install maui , because it will blow away your local build of the Android workload.
Кроссплатформенная разработка для мобильных с Xamarin
Инсталлятор Xamarin устанавливает плагин к Visual Studio, который позволяет разрабатывать приложения для популярных мобильных платформ в привычном разработчику окружении. Также устанавливается отдельная среда разработки Xamarin Studio, которая, судя по всему, является модифицированной версией MonoDevelop. Мне привычнее работать в Visual Studio поэтому примеры в этой статье будут показаны с использованием именно этой среды разработки.
После установки в Visual Studio добавляются шаблоны проектов для мобильных приложений под Android и iOS (поддерживается создание как специализированных приложений для iPad и iPhone, так и универсальных приложений, а также приложений, использующих OpenGL). Для создания приложений для iOS в Visual Studio прийдется, правда, заплатить. Этот функционал доступен либо в режиме trial, либо в business-версии инструментария, а это стоит $999 в год.
После создания проекта мы получаем все тот же API для каждой платформы, который мы имеем при нативной разработке, но синтаксис будет на C#, к тому же есть возможность использовать базовые типы .NET Framework, синтаксический сахар и прочие плюшки .NET.
Разработка для Android
После создания Android-проекта мы получаем набор файлов, в котором есть класс главного окна и набор ресурсных файлов. После длительной работы в Eclipse немного раздражает название папок в PascalCase, но к этому можно довольно быстро привыкнуть. Также есть отличия в работе с файлами ресурсов. Для того, чтобы встроенный дизайнер окон понимал файлы ресурсов с лайаутами, у них расширение изменено на .AXML вместо привычного .XML в Eclipse. Это довольно сильно раздражает, особенно если рисовать лайауты в Eclipse, а потом переносить в Visual Studio в случае если Eclipse’овский дизайнер окон больше нравится.
Встроенный дизайнер окон мне лично показался неудобным. Медленный, часто валит всю IDE, я так и не понял, как в нем по-простому переключиться между XML-видом и UI. Здесь уж точно можно сказать что писано чужими для хищников. Я для себя решил, что в Eclipse мне удобнее, привычнее, да и на экран ноутбука в Eclipse помещается больше полезной информации. Может кому-то дизайнер Visual Studio и понравится больше, на вкус и цвет фломастеры разные.
Activities
Код на C# для Mono for Android очень схож с кодом на Java.
- Для регистрации activity не надо ничего прописывать в манифесте. Для этого используется аннотация [Activity]
- Для того, чтобы сделать activity стартовой, необходимо для аннотации [Activity] указать параметр MainLauncher. Это будет равносильно заданию action = android.intent.action.MAIN и category = android.intent.category.LAUNCHER в манифесте
- Основные методы жизненного цикла activity (да и вобще все методы) имеют названия в PascalCase.
Элементы управления и обработка событий
Для получения ссылок на элементы управления, как и в Java-версии, используется метод FindViewById() . Очень порадовало наличие generic-версии этого метода, который возвращает объект нужного типа и позволяет избавиться от c-cast’ов.
Вместо listener’ов, а точнее, в дополнение к ним, для подключения обработчиков событий используются делегаты. Можно использовать и listener’ы, но это, во-первых, не .NET way, во-вторых, требует написания большего количества кода, даже по сравнению с Java. К тому же делегатов можно подключить несколько:
Не со всеми обработчиками событий в виде делегатов дела обстоят радужно. В одном из проектов обнаружилась проблема с событием View.ViewTreeObserver.GlobalLayout , у которого при использовании оператора -= не отключались делегаты-обработчики. Да вообще никак не отключались. Пришлось использовать IOnGlobalLayoutListener .
Использование Java-библиотек в .NET-проекте
- Создать проект Java Binding Library в решении.
- В папку Jars положить нужный JAR-файл (в JAR-библиотеке не должно быть AndroidManifest.xml, ибо наличие этого файла может повлечь ряд неприятных последствий. Подробнее об этом можно узнать здесь).
- Указать Build Action для JAR-файла как EmbeddedJar.
- В проекте Android-приложения добавить в References проект созданной Java Binding Library.
Работа с базами данных
Для работы с базами данных в Mono for Android предусмотрены используются классы пространства имен Mono.Data.Sqlite (используются для доступа к базам данных SQLite) и System.Data.SqlClient (для доступа к Microsoft SQL Server). Классы пространства имен System.Data.SqlClient доступны только в Business-редакции инструментов разработки. Можно также использовать классы-обертки над родным Java API для Android и сторонние разработки, например sqlite-net, в котором доступен асинхронный вариант API.
Пользоваться доступным API довольно просто. Все очень схоже с разработкой для настольных ПК:
Разработка для iOS
Элементы управления и обработчики событий
Создание элементов управления в коде ничем не отличается от аналогичной работы в Objective-C. Обработчики событий можно навешивать также как и в Android – с помощью делегатов. Также можно добавлять обработчики как в Objective-C через селекторы.
Использование нативных библиотек
В Xamarin iOS, также как и для Android, доступна возможность использования нативных библиотек. Для этих целей есть специальный тип проекта – iOS Binding Project, в который можно добавлять статические библиотеки, после чего они будут слинкованы вместе с основным проектом.
- Создать проект статической библиотеки в XCode.
- Если планируете отлаживать C# проект в симуляторе, то в настройках проекта статической библиотеки необходимо добавить архитектуру i386 в список Valid Architectures.
- Написать нужную логику (допустим у нас есть один экспортируемый класс):
Работа с базами данных
Для работы с базами данных в iOS используются те же пространства имен, что и в Android. API, соответственно, такой же. Небольшая разница может быть в мелочах. Например, для получения пути к файлу базы данных SQLite в Android есть специальный API-вызов:
В iOS же нужно использовать стандартные средства .NET:
Удаленная отладка iOS приложений из Visual Studio
В Xamarin 2.0 есть возможность отладки мобильных приложений для iOS прямо из Visual Studio. Для того, чтобы это стало возможно, необходимо иметь в локальной сети Mac с установленным XCode, iOS SDK и Xamarin Studio. Никаких дополнительных настроек производить не надо, достаточно при открытии iOS проекта в Visual Studio выбрать нужный build-сервер из списка доступных.
К сожалению данный подход не заработал с виртуальной машиной, запущенной на том же компьютере что и Visual Studio. Хотя с обычным Mac’ом в локальной сети все замечательно работает. Причин или объяснений этому пока найти не удалось, пытаюсь общаться с разработчиками по этому поводу.
Также не очень понятно, как организовывать UI-тестирование и проверку работоспособности приложения из Visual Studio. Симулятор запускается на Mac’е, похоже, что без VNC здесь не обойтись.
Кроссплатформенные библиотеки классов (Portable Class Libraries)
Xamarin предоставляют возможность создания библиотек, которые могут быть использованы (в виде кода или готовых сборок) сразу для нескольких платформ. Такие библиотеки называются Portable Class Library (PCL).
Для разработки подобных библиотек используется специальный урезанный вариант .NET Runtime и это чудесный инструмент для разработчика, значимость которого трудно переоценить, но здесь тоже не все так просто. По умолчанию в Visual Studio нельзя указать Android и iOS в качестве поддерживаемых платформ для PCL-проекта. Но это не значит, что Visual Studio сразу становится бесполезной в этом плане.
Проблему можно решить путем создания XML-файлов в папке C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0\Profile\Profile104\SupportedFrameworks для x64 систем или в папке C:\Program Files\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0\Profile\Profile104\SupportedFrameworks для x86 систем.
Android файл MonoAndroid,Version=v1.6+.xml
iOS файл VSMonoTouch,Version=v1.0+.xml
После создания этих двух файлов и перезапуска Visual Studio можно будет указывать Android и iOS в качестве поддерживаемых платформ для новых PCL-проектов или добавить эти платформы в существующие проекты через Properties -> Library -> Target Framework.
Но это еще не все нюансы.
Если вы хотите поддержку Android и iOS в PCL-проекте, то придётся отказаться от поддержки Xbox 360 и Windows Phone 7 (зато можно поддерживать Windows Phone 7.5+). Для Xbox придётся создавать еще один проект и в нем добавлять файлы из существующего PCL-проекта в виде ссылок. Или, как вариант, в одном PCL-проекте оставить все платформы от Microsoft (включая Xbox 360), а в другом оставить только iOS и Android.
Есть еще такая проблема что PCL-проект, добавленный из Visual Studio под Windows не будет участвовать в сборке решения, если открыть его в Xamarin Studio под OS X. Проект будет неактивен и будет выводиться сообщение (not built in active configuration). Решается эта проблема удалением проекта из решения и добавлением заново.
Новые возможности языка и поддержка C#5
В разработке для Android актуальным является вынесение работы с файлами, базами данных, сетью и т.д., то есть с длительными операциями, в отдельный поток. В C# 5 для реализации асинхронных операций предусмотрены специальные возможности, а именно async/await. К сожалению, в текущей версии Mono for Android и MonoTouch этих возможностей нет. Из-за этого многие довольно интересные библиотеки нельзя использовать в том виде, который для них предусмотрен. Например для работы с асинхронным API библиотеки sqlite-net приходится делать несколько финтов ушами. Радует то, что эти возможности должны стать доступны через несколько месяцев с переходом Xamarin на C# 5.
Дополнительные компоненты и библиотеки
Xamarin помимо, собственно, продажи инструментария для разработки ПО, открыли магазин по продаже сторонних компонент, многие из которых действительно очень упрощают жизнь разработчику. В магазине доступны как платные, так и бесплатные библиотеки и темы оформления. Полезность, например, бесплатных Xamarin.Auth, Xamarin.Social и Xamarin.Mobile трудно переоценить. Есть возможность публиковать собственные компоненты в этом магазине.
Неприятные моменты
- Жуткие тормоза при отладке Android-приложений, когда на довольно мощной машине с Core i7 и 8 GB RAM при останове на брейкпоинте Visual Studio зависает на 10-15 секунд. Подобное может повторяться на каждом шаге отладчика.
- Отсутствие в списке устройств, доступных для отладки приложений, некоторых устройств, подключенных к компьютеру (которые, тем не менее, видны через adb devices и на которых Eclipse отлично запускает приложения)
- Произвольные отпадания отладчика и необходимость перезапуска приложения в связи с этим.
- Отсутствие статей и учебных материалов (да, есть какие-то материалы на официальном сайте, но они покрывают не все популярные задачи)
- Наличие багов, о которых узнаешь ВНЕЗАПНО! после общения на форуме. Хотя на том же официальном форуме разработчики довольно бодро отвечают на вопросы и вообще молодцы.
- Цена на Business-редакцию очень кусается. К тому же лицензия на год, а не навсегда (немного скрашивает ситуацию наличие скидок при покупке лицензии сразу для нескольких платформ).
Приятные моменты
- При покупке лицензии сразу для нескольких платформ или сразу для нескольких рабочих мест, предусмотрена скидка.
- С выходом новой версии, в которой будет поддержка async\await разработка действительно станет проще и будет возможность использовать кучу полезных библиотек, не меняя их код.
Выводы
Инструментарий от Xamarin таки да, действительно работает и если вы планируете разрабатывать несколько приложений в год или же планируемая прибыль от разрабатываемого приложения больше чем $2k, то Xamarin SDK явно может облегчить вам жизнь и избавить от двойной работы над кодом для каждой платформы.
С другой же стороны, для Indy-разработчика цена в $1k для каждой платформы мне, например, кажется чрезмерной т.к. есть много нюансов, которые необходимо знать и\или прочувствовать на себе перед началом разработки, есть баги, которые неизвестно в каком режиме будут исправляться и неизвестно насколько их наличие может замедлить разработку конкретно вашего проекта.
Немного клёвых ссылочек!
-
. . (выложены видео семинаров).
- Выше я уже упомянул про общий код. Так вот, доля этого кроссплатформенного кода может достигать 80% или даже 90%. Понятно, что чудес не бывает и все зависит от специфики вашего приложения. Если, например, вы пишете хардкорный код для обработки аудио/видео в реальном времени, он будет платформо-зависимым, и доля общего кода снизится. Но если вы ограничиваетесь написанием бизнес-логики — тогда ситуация обратная.
- Xamarin позволяет напрямую достучаться до нативного API каждой из трех упомянутых платформ. То есть на нем можно писать и платформо-зависимый код.
- HelloHighloadToday.Android;
- HelloHighloadToday.iOS.
- заголовок («Знакомься с Xamarin!»);
- развернутый призыв к действию в следующем блоке текста;
- кнопку с надписью https://highload.today/category/teoriya;
- кнопку с надписью CLEAR;
- невидимый WebView.
Примеры
-
. . .
-
. . .
UPD: Уточнение от northicewind по поводу стоимости лицензии:
Просто и понятно о Xamarin: как разработать кроссплатформенное мобильное приложение. Пошаговая инструкция

Xamarin — это опенсорс-фреймворк для разработки кроссплатформенных мобильных приложений с использованием библиотек .NET.
Чаще всего в качестве среды разработки выбирают Microsoft Visual Studio, а в качестве языка — C#. Такое сочетание позволяет компилировать, собирать и запускать один и тот же код (общий код) для:
-
iOS (.ipa — iOS App Store Package);
В большинстве случаев созданные таким образом приложения будут работать и выглядеть на каждой из платформ как нативные (родные).
Xamarin — это не только инструмент, это некий подход к процессу разработки. Он позволяет писать большую часть общего кода на одном языке и использовать его в других проектах.
Преимущества Xamarin
Лицензия и другие условия использования
Есть две новости — хорошая и плохая. Начнем с плохой.
Стоит предупредить, что сейчас, без машины с MacOS компилировать, собирать и отлаживать Xamarin-приложения под iOS (официально) нельзя. Возможно, ограничение получится обойти, но насколько это легально?
Теперь хорошая новость: Xamarin распространяется бесплатно — в том числе и для коммерческого использования.
Документация и сторонние компоненты
У Xamarin довольно обширная документация. Она охватывает общие вопросы разработки кроссплатформенных приложений. Много внимания уделено библиотеке Xamarin.Forms. Кроме того, существуют отдельные большие блоки документации по специфическим вопросам разработки для Android и iOS.
На английском языке:
Экосистема дожила до того счастливого момента, когда для Xamarin начали пилить сторонние компоненты. Среди популярных переиспользуемых компонентов и шаблонов пользовательского интерфейса, можно выделить:
Поддержка системных требований (для Windows и для 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 .

Вкладка 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 (пустой), чтобы в сгенерированном коде не было ничего лишнего
Я также выбрал пункт Blank (пустой), чтобы в сгенерированном коде не было ничего лишнего. Так проще с ним разбираться.
Все, Solution создан! Посмотрим на его структуру:

Так как я выбрал две платформы, то дополнительно к основному проекту (HelloHighloadToday) VS создала еще два (платформо-зависимых):
По умолчанию жирным выделен проект HelloHighloadToday.Android, но важно понимать, что основным проектом остается HelloHighloadToday. Без этого проекта невозможно заставить один и тот же код работать на остальных двух.
Hello, HighloadToday: как работает код
Теперь разберемся, как работает сгенерированный код.
Посмотрим на структуру основного проекта — HelloHighloadToday. Здесь нас интересуют пять файлов: App.xaml, App.xaml.cs, MainPage.xaml, MainPage.xaml.cs и AssemblyInfo.cs.

В структуре HelloHighloadToday выбираем нужные файлы
AssemblyInfo.cs хранит настройки компиляции для Xamarin-приложения. Об этом файле — пока все.
Файлы App.xaml и App.xaml.cs
Есть более интересные ф айлы App.xaml и App.xaml.cs. Они отвечают за запуск приложения (для любителей английского: App — Application). Файл App.xaml — первая стартовая точка приложения.

По его расширению можно догадаться, что код внутри написан на XAML (язык разметки на основе XML). Этот декларативный язык обычно используется для описания пользовательского интерфейса или ресурсов. В этом файле обычно описываются глобальные ресурсы (например, стили), которые можно использовать внутри всего приложения. Нам тут пока описывать нечего, но в качестве примера можно посмотреть на такое:
С описанием UI мы встретимся чуть позже.
App.xaml работает в паре с файлом App.xaml.cs. Это вторая стартовая точка.

В этом файле создается пользовательский класс App — наследник класса Application (Приложение). Полное название этого класса определяется в файле App.xaml. В нашем случае это:
В конструкторе этого класса есть важный вызов метода InitializeComponent() , который отвечает за начальную инициализацию объекта нашего класса App, производного от класса Application. Там же, в конструкторе, устанавливается наша главная страница приложения ( MainPage , о ней пойдет речь далее).
Кроме того, в этом же классе Visual Studio заботливо сгенерировала пустые обработчики основных событий для типичного мобильного приложения — OnStart() , onSleep() и onResume() . Писать внутри свой код или не писать — целиком и полностью решаем мы с вами (то есть разработчики, которые используют Xamarin). Тут же можно подписаться и на другие события.
Файлы MainPage.xaml и MainPage.xaml.cs
Эта пара файлов состоит примерно в таких же отношениях, как App.xaml и App.xaml.cs:
Только в 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
Это код, сгенерированный при создании страницы на базе шаблона ContentPage (C#).
UI с XAML

XAML-код, сгенерированный при создании страницы на базе шаблона ContentPage
Это XAML-код, сгенерированный при создании страницы на базе шаблона ContentPage.

Сs-код, сгенерированный при создании страницы на базе шаблона ContentPage
Это cs-код, сгенерированный при создании страницы на базе шаблона ContentPage.
Здесь файл .xaml с описанием UI отделен от .cs-файла. Тогда имеет смысл договориться, что во втором файле будем писать только логику взаимодействия с визуальным интерфейсом. Такой подход считается более рациональным: c декларативным стилем XAML структура UI выглядит более наглядно, код проще понимать и поддерживать, благодаря разделению над каждым из двух файлов может работать отдельный специалист. И это явно реверанс в сторону любителей HTML.
В обоих случаях нужно вносить изменения в код ручками, потому что у Xamarin.Forms нет Дизайнера (Конструктора форм). Но если создать Solution вроде Android App (Xamarin), то там Дизайнер присутствует. Только это уже тема для другой статьи.
Хорошо, так давайте же внесем эти изменения!
Делаем свой UI с XAML и обработкой событий
Усложним сгенерированный пример. Сформулируем ТЗ на наше Xamarin-приложение HelloHighloadToday:
1. Показать приветственный экран. Он должен содержать:
2. По нажатию кнопки с надписью https://highload.today/category/teoriya обеспечить показ страницы по указанной ссылке: WebView должен стать видимым.
3. По нажатию кнопки с надписью CLEAR обеспечить возврат приложения к состоянию 1 (то есть спрятать WebView).
Я не буду рассказывать про сами элементы UI в расчете на то, что вы с ними знакомы или быстро сможете познакомиться.
Перепишем сначала файл MainPage.xaml. Я, не сильно раздумывая, выбрал терпимый вариант размещения элементов визуального интерфейса. Вы можете сделать по-своему:
Теперь обработаем нажатия на кнопки:

Обрабатываем нажатия на кнопки
Вот такая нехитрая логика.
Запуск под 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) выполняется инициализация и старт приложения.

Код, сгенерированный Visual Studio
В этом коде я не менял ничего.
Отлаживать приложение можно и в эмуляторе. Но для этого ваша машина должна поддерживать виртуализацию и работать достаточно шустро.
Посмотреть список виртуальных устройств или добавить новое можно через Tools -> Android -> Android Device Manager.
Если вы, так же, как я, запускаете приложения на реальном устройстве, то нужно выполнить несколько простых манипуляций с вашим смартфоном (или что там у вас c Android OS):
1. Подключить устройство к компьютеру по USB.
2. Зайти в Настройки -> О телефоне и щелкнуть по Номеру сборки 7 раз.

Необходимо кликнуть по Номеру сборки 7 раз
3. Зайти в Настройки -> Система и обновления и выбрать пункт Для разработчиков:

Необходимо выбрать пункт «Для разработчиков»
4. Включить сначала опцию Разрешить отладку по ADB только при зарядке, а потом опцию Отладка по USB. Первая опция вроде бы не обязательна, но без нее у меня не работало:

Включить необходимые опции
5. И еще один шаг на всякий случай. Если Visual Studio не может найти ваше устройство после всех предыдущих шагов — выполните Tools -> Android -> Restart Adb Server :

Если Visual Studio не может найти ваше устройство после всех предыдущих шагов
6. Проверьте, чтобы указанные в настройках пути вели, куда надо. Иначе Visual Studio просто не найдет нужные версии SDK и JDK.

Проверьте, чтобы указанные в настройках пути вели, куда нужно
7. Чтобы успешно скомпилировать приложение, нужно выбрать версию ОС, которая установлена на вашем устройстве (или виртуальном устройстве, если используете эмулятор).

Выберите версию ОС, которая установлена на вашем устройстве
8. Для запуска приложения на устройстве номер версии Android OS не должен быть меньше указанного в настройках манифеста ( Minimum Android version) :

Попробуйте подключить старый Andorid, и увидите, что будет (спойлер: ничего не будет!).
Вернемся к нашему проекту
Нам остается только запустить Xamarin-приложение на устройстве Android. Сборка произойдет автоматически:
![]()
Запускаем запустить Xamarin-приложение


Если нажать на на кнопку с надписью https://highload.today/category/teoriya
Действительно появляется WebView с соответствующим контентом.
Нажав на кнопку с надписью CLEAR , возвращаемся к первому экрану.
Отлично, все работает в соответствии с нашим ТЗ и даже не падает, когда я закрываю приложение, смахивая его с дисплея моего смартфона.
Публикация приложения
Чтобы загрузить приложение в Google Play, нужно иметь соответствующий аккаунт и выполнить целый ряд требований. Описание этого процесса выходит за рамки моего рассказа и превышает всякие объемы приличия. Уж простите. Если сильно нужно, то с этой статьи можно начать квест (там и для iOS, и для Android OS). Но сейчас не переключайтесь, пожалуйста.
Потому что здесь я расскажу, как правильно скомпилировать проект для публикации, как создать ключ, подписать и собрать готовый к публикации .apk-файл.
В Visual Studio на панели инструментов под главным меню выбираем Release вместо Debug:

Под главным меню выбираем Release
В Solution Explorer выбираем Android-проект, нажимаем правую кнопку мыши и открываем его свойства (левой кнопкой на Properties ):

Нажимаем левой кнопкой мыши на Properties
Далее переходим в Android.Manifest. Тут почти ничего менять не пришлось (как минимум это справедливо для Visual Studio Community 2019 16.11.0). Понадобилось только выбрать иконку приложения ( Application icon ). Эту иконку (точнее набор копий иконки разных размеров) Xamarin выдает по умолчанию. Можно заменить на свою в папке Resources текущего проекта:

Иконку можно заменить на свою в папке Resources
На следующей вкладке Android.Options убираем галочку с опции Enable developer instrumentation (debugging and profiling). Так безопаснее. Сегодня спонсор паранойи — корпорация Microsoft:

Убираем галочку с опции Enable developer instrumentation
Сохраняем и закрываем окно со свойствами и опять попадаем в Solution Explorer. Там последовательно выполняем два действия:
1. Очищаем проект ( Clean ).
2. Пересобираем проект (Rebuild).

Очищаем и пересобираем проект
Выбираем Android-проект, нажимаем правую кнопку мыши и затем — Archive .

Выберите Android-проект, нажмите правую кнопку мыши и затем — Archive
Дожидаемся, пока сформируется файл .apk. Сформировался? Замечательно. Но пока он не подписан. Поэтому продолжаем.
Нажмем на кнопку Distribute:

Нажмите на кнопку Distribute
В появившемся окне выберем Ad Hoc (мы ведь создаем apk без загрузки в Google Play):

Далее нужно создать Ключ (Android Key Store) , которым будем подписывать наш файл приложения:

Ниже пример заполнения полей. Нужно заполнить все поля и нажать Create .
Важно: запомните пароль , который вы придумали, так как через пару-тройку шагов вновь потребуется его ввести!

После создания Ключа нужно нажать Save As для сохранения подписанной версии файла .apk:

Нажмите Save As
Здесь можно ввести произвольное название для файла:

Вводим название файла
При сохранении потребуется ввести пароль, который мы вбили при создании Android Key Store.
Все, мы получили .apk-файл, который можно скопировать на телефон или разослать кому-то по почте. Пишите письма. Пока!