Улучшаем приложение: Миграция между версиями Unity3d

Содержание:

Итак друзья, сегодня мы поговорим про очень важное требование для разработчиков от корпорации Google к приложениям на Google Play. Не секрет, что с 1 августа 2019 года все приложения должны поддерживать 64-битную архитектуру. Многие люди, особенно энтузиасты, для которых создание приложений просто хобби забывают о поддержке своих приложений. Ну или просто откладывают важные обновления.

Кому будет полезна данная статья?

  • Тем кто интересуется миграцией своих проектов между разными версиями Unity3d фреймворка;
  • Тем кто создал приложения на Unity3d (для версий не поддерживающих архитектуру ARM64-v8a <=5.6, 2017.1, 2017.2, 2017.3);
  • Тем кто использует нативный код для процессорных архитектур ARM-v7 и ARM-v8;
  • Тем кто использует сторонние фреймворки для создания Android приложений;
  • Начинающим разработчикам приложений.

Кому нет необходимости читать статью дальше?

  • Если вы написали приложение на языках Java, или Kotlin и не использовали нативный код написанный на C/C++;
  • Если вы не используете сторонние библиотеки.

Корпорация Google всегда предупреждает заранее и у вас ещё есть время привести все в соответствие требованием. Поскольку все 32-битные приложения armeabi-v7a идут на 64-битной архитектуре arm-v8a вы могли создать приложение и забыть об этом. Будьте внимательны и проверьте поддерживает ли ваше приложение данное требование.

Архитектуры процессоров, возможные сложности и методы их решения

Производителей электронного оборудования и аппаратных платформ достаточно много. : x86, SPARC, ARM, ARMv8-A, Alpha, Arc, Itanium, SMIPS,MIPS-LE, PowerPC, TILE. Сейчас, практически невозможно знать все тонкости и нюансы аппаратных архитектур. Обычно, в университетские курсы входит знакомство с набором x86 инструкций. Кроме того, архитектуры со временем устаревают.

Если бы все процессоры имели одинаковую архитектуру, тогда это существенно упростило бы жизнь программистам. Но так не бывает и не будет из-за следующих причин:

  1. Не все архитектуры открытые, многие из них запатентованы и защищены законом об авторском праве;
  2. Архитектуры строятся с учетом специфики задач и данных с которыми они будут работать;
  3. Инструкции меняются, или добавляются вместе с появлением новых технологий.

Так MIPS архитектуры и PowerPC используются в роутерах, некоторых простых телефонах. Для мобильных устройств более типичной архитектурой является ARM. Для ПК основными архитектурами являются x86 и x86_64. Несмотря на то что Intel и AMD выпускают процессоры с одинаковой x86_64 архитектурой, реализация некоторых инструкций у них своя. В статье которая посвящена уязвимостям Meltdown и Spectre мы говорили об одной из таких инструкций PAUSE. Читайте также: Как улучшить производительность Linux?

Архитектуры графических процессоров ориентированны на работу с числами с плавающей точкой. Эта их особенность особенно хороша когда вы тренируете искусственную нейронную сеть. Поскольку значения интенсивности цветов на изображениях перед их подачей на сверточную нейронную сеть нормализуют в промежутке от [-0.5;0.5], то использование графических карт ускоряет тренировку. В реальной жизни скорость тренировки нейронной сети зависит не только от количества графических ядер, но и от архитектуры СНС и выбора активационных функций.

Что такое нативный код?

Как вы угадали, количество машинных инструкций очень большое и невозможно их всех держать в голове. Что бы не потеряться в огромном разнообразии знаний, инженеры компании Sun создали виртуальную машину Java. Через некоторое время компанию Sun Microsystems приобрела корпорация Oracle.

Виртуальная машина Java выполняет промежуточный код компилируя его в машинный код. Машинных инструкций много, а промежуточных инструкций меньше. Это все похоже на архитектуру созданную поверх существующей архитектуры и упрощает жизнь программиста. Вам достаточно быть Java программистом, чтобы ваши программы запускались на множестве аппаратных архитектур. Вам не нужно углубляться в суть аппаратных архитектур, просто используйте Java.

Машинный код называется нативным кодом, потому что он будет работать только на одной аппаратной архитектуре. Нативный код рекомендуют избегать, но бывают случаи, когда без его применения не обойтись. Например, когда вам необходимо использовать специфические аппаратные возможности какой-нибудь архитектуры. Во всех остальных случаях рекомендуют использовать промежуточный код.

Какие языки программирования поддерживают промежуточное кодирование?

Кроме технологии Java Virtual Machine, похожие вещи применяет Microsoft. Корпорация Microsoft создала свою реализацию виртуальной машины которая выполняет промежуточный код и назвала технологию dot Net. Такими действиями они хотели получить преимущество в сегменте мобильных ОС. Рынок мобильных приложений огромен и они не хотели уступать источник своего обогащения другим конкурентам.

Unity3d применяет технологию промежуточного кодирования от корпорации Microsoft. Если вы откроете приложение созданное при помощи технологии Net, тогда в шестнадцатиричном редакторе вы увидите вначале метку MSIL. MSIL — это аббревиатура от слов Microsoft Intermediate Language (промежуточный язык Microsoft). Если приложение нативное, тогда вы увидите метку MZ, или другую метку.

Все языки входящие в набор Microsoft Visual Studio позволяют создать MSIL бинарный выполняемый файл. Таким образом, приложения могут работать на MacOS и Linux. В Linux есть своя реализация технологии Net. Библиотека Mono позволяет выполнять промежуточный код от Microsoft на Linux и MacOS.

Python в режиме интерпретации

Язык программирования Python также имеет виртуальную машину Python и использует свою технологию промежуточного кодирования. Поскольку виртуальная машина Python открыта и доступна для большинства архитектур, её используют в роутерах Cisco. Чтобы применять Python не нужно быть программистом, достаточно уметь пользоваться справкой help() и dir(). Введите название объекта в качестве аргумента чтобы получить справку и список доступных функций.

Разрушаем мифы: Насколько страшен переход к новым правилам

В большинстве новостных ресурсов все настолько драматизировали, что пошли страшилки касательно удаления приложений. Особенно это относится к русскоязычным ресурсам. Давайте вместе с вами найдем ответы на все вопросы и устраним все спекуляции.

Google Play roadmap
Roadmap для Google Play
(Источник: Google)

Кого августовский переворот не коснется? Чем старше ваш проект, тем сложнее будет мигрировать. Поэтому это не коснется приложений созданных в Unity <=5.6. Как вы видите, Unity разработчикам пошли на встречу и до 2021 года ничего страшного не случится. Этого периода вполне достаточно, чтобы переписать весь код своего приложения и пересобрать все сторонние зависимости.

Указанные изменения не коснутся приложений явно предназначенных для Wear OS и Android TV. Этот сегмент рынка не настолько насыщен разнообразием архитектур, как рынок смартфонов и планшетов. Кроме всего, это не коснется приложений не распространяемых на устройства под управлением Android Pie и следующих версий (уровень API 28+).

Google Play will stop serving apps without 64-bit versions on 64-bit capable devices, meaning they will no longer be available in the Play Store on those devices.

android-developers.googleblog.com

Что же будет на самом деле? Ваше приложение не будет видно в Google Play на устройствах с 64-битной архитектурой ARM-v8a. Это повлияет на позицию в поисковой выдаче на Google Play. На всех остальных, устройствах оно будет доступно. Собственно, новые ОС от Google и так ориентированны в основном под 64-битные архитектуры. Разработчики приложений, в любом случае, добавят поддержку 64-битных архитектур. Охват большей аудитории в их интересах. Cocos2d, Unity3d и Unreal все поддерживают 64-битный режим. На кого же рассчитана эта новость?

Такими действиями Google провоцирует потребителей к покупке новых устройств. Заголовки в СМИ послужили поводом для огромного количества спекуляций среди обычных людей. Самое печальное, что прочитав такие заголовки люди ошибочно думают что в Google Play исчезнут все приложения под 32-битные устройства. Нет не исчезнут, можете не торопится покупать новые устройства. Для обычного пользователя пока ничего не изменится.

Все трудности миграции Unity3d проектов

Кажется что все просто, когда есть исходный код и кросскомпилятор. Однако, сторонние зависимости могут замедлить вашу миграцию. Чем больше стороннего кода и возможностей которые он предлагает, тем больше неожиданных проблем могут возникнуть. Из версии в версию происходит отказ от некоторых устаревших возможностей и создание новых возможностей. Новые возможности не всегда оперативно поддерживаются другими программными продуктами.

Для примера, Cocos2d поддерживал архитектуру ARM64-v8 ещё с 2015 года. Unity3d на то время этой возможности не поддерживала. В итоге, в тройке лидеров по созданию мобильных игр она стала последней внедрившей данную технологию после Unreal и Cocos2d. У каждого из этих движков есть свои преимущества и недостатки. Если вы не знакомы с ними и планируете написать свое приложение, тогда рекомендую ознакомится с пользовательскими форумами.

Как упростить миграционный процесс?

Во всех крупных компаниях и проектах создают план (Roadmap). Люди ответственные за развитие проектов излагают свое видение развития программных продуктов. Если вы собрались интегрировать одно из существующих решений реализующих требуемый функционал, тогда внимательно ознакомьтесь с ним. Но для начала, ответьте себе на важные вопросы.

  1. Ваше приложение будет многопользовательским, или однопользовательским?
  2. На какую группу людей рассчитано ваше приложение?
  3. На каких аппаратных платформах оно будет функционировать?
  4. Какие возможности вы будете реализовывать в будущем?
  5. Каким образом будет осуществляться контроль качества и внедрения приложения на целевой рынок?

Четвертый вопрос один из самых важных для людей ответственных за интеграцию решений. Представьте, что вы написали код реализующий некоторую возможность, а потом эту возможность исключили. Это очень печально, правда? Вам придется переписывать код. Поэтому не спешите создавать приложения и хорошо обдумайте все возможные нюансы прежде чем что-либо реализовывать.

Трудности миграции проекта Cube Mixer

Экспериментальную поддержку архитектуры ARM64-v8 внедрили в Unity 2018.1. Но вместе с внедрением новых возможностей они убрали старый добрый механизм создания многопользовательских игр. Раньше для создания многопользовательской игры использовалась комбинация высокоуровневого HLAPI и низкоуровневого LLAPI. По просьбам и жалобам трудящихся в компании решили отказаться от этого API. Ниже приведен план дорожная-карта развития Unity3d.

Unity3d unet deprecation
Переход от старого Unet к CGS

Старый добрый Unet меня, как и множество других разработчиков вполне устраивал. О нем, я не могу сказать ничего плохого. Это была хорошая вещь. Начиная с версии 2018.2 убран класс Network, поэтому применить Network.time уже не получится. Некоторые использовали его для синхронизации времени.

В Unity3d 2018.2 убрали HLAPI, а LLAPI был помечен как устаревший. Через некоторое время его также убрали. Сейчас разработчики вынуждены переписывать код под новое решение. Как вы видите на изображении выше, ещё не все готово в CGS. Интерфейс ещё достаточно сырой и приходится ждать конца 2019 года. Ко всему прочему, отсутствует адекватная документация по новым функциям. Без документации очень трудно разрабатывать приложение. Я внимательно слежу за блогами разработчиков Unity3d и постараюсь вас порадовать настолько быстро, насколько это возможно.

Сторонние библиотеки: Firebase

Разные сторонние библиотеки собираются на разных версиях Net Framework. Так в версии платформы Net 4.0, появилась динамическая типизация. Если вы попробуете скомпилировать код содержащий переменные типа «dynamic» для платформы Net 2.0, или Net 3.5, вы получите ошибку. В старых версиях такой поддержки не было и собрать современную библиотеку, без внесения правок в исходный код, на них не получится.

Так Firebase конфликтовал со старой версией Unity3d 2017.1. Через некоторое время это исправили. Сторонние зависимости не должны быть слишком старыми, но и переход на полностью новые не протестированные решения достаточно проблематичен. Для разработчика главное выбирать золотую середину.

Во всяком случае, есть средства тестирования приложений Firebase Test Lab. Поскольку я пока не являюсь счастливым обладателем устройства на базе архитектуры ARM64-v8a, я не могу оперативно исправлять приложение для этой архитектуры. Сейчас благодаря облачному тестированию я могу тестировать свое приложение на самом современном оборудовании. Очень жаль что там установлена квота 5 тестирований за день, но мне этого достаточно.

Unity3d и API compatibility level

Unity3d начал поддерживать платформу Net 4.x с 2017 года. Хотя данная платформа существовала задолго до 2017 года. Людям которые любят динамическую типизацию в Python изменения в Net 4.0 очень понравились. Я имею ввиду новый тип переменных «dynamic».

Unity3d .Net API compatibility
Поддержка .Net 4.x в Unity3d

Почему они не спешили переходить на эту платформу? Во первых, код применяющий возможности новой платформы не скомпилируеться для старой платформы. Все их действия предназначены для удобства разработчиков. Повторная сборка библиотек под новую платформу отнимает время.

Библиотеки компилируемые в промежуточный MSIL-код называются управляемыми (Managed). Они могут выполнятся на любых процессорах (AnyCPU). Существует очень важный нюанс, на который я хочу обратить ваше внимание, это дополнительный подтип «Any CPU 32-bit preffered» введенный в платформу Net начиная с версии 4.5 [1].

Target Architecture
Unity3d не предоставляет выбор «Any CPU 32-bit preffered», только «Any CPU»

Чтобы посмотреть какие флаги используют dll файлы в вашем проекте воспользуйтесь CorFlags.exe, которая лежит где-то в подпапках каталога Program Files. Эта утилита позволяет поменять флаги для Managed библиотек. Без опций она просто покажет текущее состояние флагов.

Version   : v4.0.30319 
CLR Header: 2.5 
PE        : PE32 
CorFlags  : 131075 
ILONLY    : 1 
32BITREQ  : 0 
32BITPREF : 1
Signed    : 0

Как я уже говорил, без нативного кода обойтись не всегда получается. Бывает такое, что нативный код под 64-битную платформу не собран. Временно можно обойтись 32-битным кодом. Если 32BITPREF для управляемого кода установлен в 1, тогда ваша библиотека будет искать нативную 32-битную dll даже на машине с 64-битной архитектурой. Для этого введите:

CorFlags.exe /32BITPREF+ name_of_your_lib.dll

Выводы

Все меняется и в современном мире достаточно тяжело успевать за технологиями. Но для разработчиков присутствуют инструменты способные упростить разработку приложений. Одно из таких решений — Firebase TestLab. Это решение помогает оптимизировать приложение под огромное количество устройств.

Источники информации:

  1. What AnyCPU Really Means As Of .NET 4.5 and Visual Studio, Microsoft blogs.

Оставьте комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *