На днях задумал я попробовать использовать Visual Studio with Xamarin для написания кросс-платформенного кода сразу под три мобильные платформы. Так как раньше имел дело с AndroidStudio — мне не хватало возможности портирования кода на другие платформы.
В описании Visual Studio Community 2017 говорится красиво, что мол единая бизнес-логика для iOS, Android и Windows 10, единый подход к созданию элементов управления через Xamarin.Forms, собственный эмулятор Xamarin Instant Player и прочие плюшки. А зачем платить больше, если можно бесплатно?
Долго не думая скачиваю и начинаю устанавливать VisualStudio, выбираю нужные опции и указываю путь на диске D. И почти сразу получаю предупреждение что места на диске C совсем не осталось. Как же так?
А оказывается, кроме VisualStudio на диск С, в папку «Program Files» падает огромное количество инструментов, компонентов и утилит. Как я потом понял перенести их нельзя. Они должны быть именно в папке на системном диске (у меня SSD диск C и на нем всего 5 Гб свободного места). Конечно есть вариант создать симлинки к папке на диске D, но на работающей системе я боюсь экспериментировать.
В итоге для эксперимента решаю установить VisualStudio в эмуляторе VirtualBox (он бесплатный и достаточно функциональный). Дело за малым. И вот все установлено, и я создаю первое приложение HelloWorld на C# из шаблонов.
Пытаюсь запустить на эмуляторе и получаю облом. Оказывается Hyper-V надо отключить, с ним HAXM не совместим. Делаю по инструкции
Перезагружаю виртуалку и… ничего. Та же самая ошибка.
Ну думаю ладно, попробую через PowerShell
Перезагружаю виртуалку и опять ошибка.
Выключаю виртуалку, и в ее настройках выключаю полностью виртуализацию (параметр Система > Ускорение > Интерфейс паравиртуализации > «Отсутствует»), при том что VT-X/AMD-V остается включенным!
Запускаю виртуалку и нажимаю на кнопку отладки во встроенном эмуляторе VisualStudio. Теперь студия радостно сообщает что у меня вообще нет VT-X (хотя процессор Intel Core i5 + эмуляция чипсета ICH9). Какие комбинации не пробовал — результат один. Встроенный эмулятор студии на VirtualBox не запускается от слова вообще. Такая же проблема и с AndroidStudio на виртуалке — у нее не стартует Android Emulator.
Пытаюсь установить HAXM на виртуалку, но к сожалению безуспешно.
Почесав мозг, натыкаюсь на такой вот feature-request, где пользователи просят сделать HAXM внутри VirtualBox. Судя по всему это пока не реализовано в отличие от того же VMWare.
Ну что же, как человеку со стажем, не в первый раз прикручивать бубен. Надо запускать эмулятор на хосте и давать доступ виртуалке по сети. И вот тут встает проблема — достучаться до эмулятора не получается. Его IP (10.0.2.15) лежит вне диапазона моей сети (192.168.1.х). Переназначение IP сетевым картам ни на хосте, ни на виртуалке ничего не дает. Судя по всему сервис ADB слушает только интерфейс 127.0.0.1, как я понимаю с целью безопасности.
Попутно нахожу интересную статью про доступ к эмулятору из виртуалки, но к сожалению немного устаревшую (Xamarin Android Player уже не поддерживается и образы для него также не обновляются. Последний идет с API 23). Поэтому решаю все таки добиться работы с андроидовским эмулятором.
Наконец делаю по инструкции проброс портов с помощью собранной программы из исходников (скомпилированный файл уже ушел в небытие). Вариант с пробросом портов используя netsh не проходит — в ней нельзя в качестве назначения указывать 127.0.0.1 (пруф).
Затем делаю «adb kill-server» на хосте и на виртуалке. На виртуалке пишу «adb connect 192.168.1.2 :5585» и… получаю «adb server version (36) doesn't match this client (39); killing...». Уже хорошо, но в чем проблема?
Оказывается у меня два сервиса adb на виртуалке. Один сервис лежит в «C:\Users\\AppData\Local\Android\sdk\platform-tools» а второй в «C:\Program Files (x86)\Android\android-sdk\platform-tools». Один установился с AndroidStudio, второй с VisualStudio. Беру тот, который шел с AndroidStudio и еще раз пробую. Ура! На этот раз соединение установлено! Получаю «connected to 192.168.1.2:5585».
В VisualStudio автоматически выскакивает мой запущенный образ в Андроид эмуляторе на хосте. Счетчик соединений в программе PortForwarding показывает активное соединение (оно должно быть одно).
И наконец вот он — результат, которого так долго ждал:
Теперь несколько выводов, ради которых я затевал эту проверку:
1. Отладка таким способом не стабильна. Периодически происходят зависания при сборке проекта, выдаются ошибки которые устраняются перезапуском VisualStudio и эмулятора.
2. Запуск AndroidStudio на виртуалке выбивает соединение ADB с хостом. Следовательно для AndroidStudio на виртуалке нужно искать другие варианты отладки с эмулятором, или использовать физическое устройство.
3. Физическое устройство не нужно отлаживать через сетевой порт. Виртуалка его видит как устройство USB (только надо подключить его в настройках).
И немного оффтопа:
Вот теперь сижу и думаю, а стоит ли вообще так заморачиваться, чтобы тянуть за собой фреймворк?
В описании Visual Studio Community 2017 говорится красиво, что мол единая бизнес-логика для iOS, Android и Windows 10, единый подход к созданию элементов управления через Xamarin.Forms, собственный эмулятор Xamarin Instant Player и прочие плюшки. А зачем платить больше, если можно бесплатно?
Долго не думая скачиваю и начинаю устанавливать VisualStudio, выбираю нужные опции и указываю путь на диске D. И почти сразу получаю предупреждение что места на диске C совсем не осталось. Как же так?
А оказывается, кроме VisualStudio на диск С, в папку «Program Files» падает огромное количество инструментов, компонентов и утилит. Как я потом понял перенести их нельзя. Они должны быть именно в папке на системном диске (у меня SSD диск C и на нем всего 5 Гб свободного места). Конечно есть вариант создать симлинки к папке на диске D, но на работающей системе я боюсь экспериментировать.
В итоге для эксперимента решаю установить VisualStudio в эмуляторе VirtualBox (он бесплатный и достаточно функциональный). Дело за малым. И вот все установлено, и я создаю первое приложение HelloWorld на C# из шаблонов.
Пытаюсь запустить на эмуляторе и получаю облом. Оказывается Hyper-V надо отключить, с ним HAXM не совместим. Делаю по инструкции
bcdedit /set hypervisorlaunchtype off
Перезагружаю виртуалку и… ничего. Та же самая ошибка.
Ну думаю ладно, попробую через PowerShell
Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Hypervisor
Перезагружаю виртуалку и опять ошибка.
Выключаю виртуалку, и в ее настройках выключаю полностью виртуализацию (параметр Система > Ускорение > Интерфейс паравиртуализации > «Отсутствует»), при том что VT-X/AMD-V остается включенным!
Запускаю виртуалку и нажимаю на кнопку отладки во встроенном эмуляторе VisualStudio. Теперь студия радостно сообщает что у меня вообще нет VT-X (хотя процессор Intel Core i5 + эмуляция чипсета ICH9). Какие комбинации не пробовал — результат один. Встроенный эмулятор студии на VirtualBox не запускается от слова вообще. Такая же проблема и с AndroidStudio на виртуалке — у нее не стартует Android Emulator.
Пытаюсь установить HAXM на виртуалку, но к сожалению безуспешно.
Почесав мозг, натыкаюсь на такой вот feature-request, где пользователи просят сделать HAXM внутри VirtualBox. Судя по всему это пока не реализовано в отличие от того же VMWare.
Ну что же, как человеку со стажем, не в первый раз прикручивать бубен. Надо запускать эмулятор на хосте и давать доступ виртуалке по сети. И вот тут встает проблема — достучаться до эмулятора не получается. Его IP (10.0.2.15) лежит вне диапазона моей сети (192.168.1.х). Переназначение IP сетевым картам ни на хосте, ни на виртуалке ничего не дает. Судя по всему сервис ADB слушает только интерфейс 127.0.0.1, как я понимаю с целью безопасности.
Попутно нахожу интересную статью про доступ к эмулятору из виртуалки, но к сожалению немного устаревшую (Xamarin Android Player уже не поддерживается и образы для него также не обновляются. Последний идет с API 23). Поэтому решаю все таки добиться работы с андроидовским эмулятором.
Наконец делаю по инструкции проброс портов с помощью собранной программы из исходников (скомпилированный файл уже ушел в небытие). Вариант с пробросом портов используя netsh не проходит — в ней нельзя в качестве назначения указывать 127.0.0.1 (пруф).
Затем делаю «adb kill-server» на хосте и на виртуалке. На виртуалке пишу «adb connect 192.168.1.2 :5585» и… получаю «adb server version (36) doesn't match this client (39); killing...». Уже хорошо, но в чем проблема?
Оказывается у меня два сервиса adb на виртуалке. Один сервис лежит в «C:\Users\\AppData\Local\Android\sdk\platform-tools» а второй в «C:\Program Files (x86)\Android\android-sdk\platform-tools». Один установился с AndroidStudio, второй с VisualStudio. Беру тот, который шел с AndroidStudio и еще раз пробую. Ура! На этот раз соединение установлено! Получаю «connected to 192.168.1.2:5585».
В VisualStudio автоматически выскакивает мой запущенный образ в Андроид эмуляторе на хосте. Счетчик соединений в программе PortForwarding показывает активное соединение (оно должно быть одно).
И наконец вот он — результат, которого так долго ждал:
Теперь несколько выводов, ради которых я затевал эту проверку:
1. Отладка таким способом не стабильна. Периодически происходят зависания при сборке проекта, выдаются ошибки которые устраняются перезапуском VisualStudio и эмулятора.
2. Запуск AndroidStudio на виртуалке выбивает соединение ADB с хостом. Следовательно для AndroidStudio на виртуалке нужно искать другие варианты отладки с эмулятором, или использовать физическое устройство.
3. Физическое устройство не нужно отлаживать через сетевой порт. Виртуалка его видит как устройство USB (только надо подключить его в настройках).
И немного оффтопа:
- Запуск уже установленного приложения с Xamarin.Forms занимает существенно много времени (гораздо больше чем обычные Java проекты).
- В придачу к очень немаленькому размеру приложения (HelloWorld занимает более 12 Мб) мы получаем еще Mono Shared Runtime (42 Мб) и Xamarin Android support (для API23 это 23 Мб).
Вот теперь сижу и думаю, а стоит ли вообще так заморачиваться, чтобы тянуть за собой фреймворк?