Как исправить конфигурацию в скриптов андроид игр
Перейти к содержимому

Как исправить конфигурацию в скриптов андроид игр

  • автор:

Практическое руководство по оптимизации для мобильных

Это руководство предназначено для новичков в мобильном геймдеве. Для тех, кто испытывает трудности при планировании и прототипировании новой мобильной игры (или портировании уже существующего проекта). Также этот раздел будет полезен в качестве справки для каждого, кто делает мобильные или браузерные игры (с целевой платформой — старые ПК или нетбуки).

Оптимизация вообще широкая тема, и то как вы ее сделаете, целиком зависит от вашей игры, поэтому данное руководство следует рассматривать как некое введение или ссылку, а не пошаговое руководство.

Мобильные устройства не созданы одинаковыми

Информация здесь предполагает аппаратное обеспечение на уровне чипсета Apple A4, который используется в оригинальных iPad, iPhone 3GS и третьем поколении iPod Touch. Из Android предполагается устройство подобное Nexus One, или большинства устройств, работающих на Android 2.3 Gingerbread. В основном, эти устройства были выпущены в начале 2010 года. Эти устройства старее, медленнее современных, но так как они составляют большую часть рынка, их также следует поддерживать.

Есть очень быстрые и очень медленные телефоны. Вычислительные мощности мобильных устройств растут с потрясающей скоростью. Для нового поколения мобильной GPU, быть в 5 раз быстрее своего предшественника — обычное дело. Скорость мобильных устройств уже сравнима со скоростью ПК.

Для обзора технических характеристик мобильных устройств от Apple, см. Hardware.

Если вы хотите разрабатывать под мобильные устройсва, которые станут известными в будущем, или эксклюзивные high end устройства прямо сейчас, вы можете это сделать. См. Мобильные устройства будущего.

Очень низкая производительность (например, iPhone 3G или первое и второе поколение iPod touches) требует особого внимания к оптимизации. В противном случае могут возникнуть проблемы когда покупатели, не обновившие устройства, будут покупать ваши приложения. Если же вы делаете бесплатное приложение, можно не беспокоится о поддержке старых устройств.

Оптимизацию не следует считать последней стадией разработки проекта

Британский ученый Майкл А. Джексон часто цитируется своими Правилами оптимизации программ:

_Первое правило оптимизации программы: не делаете ее. Второе правило оптимизации программы (только для экспертов!): не делайте ее пока что.

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

Однако, если вы разрабатываете мобильные игры, есть еще одно мнение: аппаратное обеспечение, представленное сейчас на рынке, сильно ограничено по сравнению с компьютерами, которые мы используем для работы. Поэтому высок риск того, что ваша ваша игра не будет работать на большинстве устройств и оптимизацию рекомендуют делать с самого начала разработки.

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

Оптимизация: Не только для программистов

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

  • На художника ложится большая ответственность. Если дизайн игры предполагает атмосферность и освещение, их можно нарисовать в текстурах вместо запекания.
  • Каждый раз, когда что-либо может быть запечено, художники могут готовить контент для выпекания, вместо рендеринга в реальном времени. Это позволяет им игнорировать технические ограничения и работать свободно.

Планируйте игру так, чтобы во время исполнения она работала “плавно”.

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

  • Практические методы для оптимизации рендеринга
  • Практические методы для оптимизации скриптинга и геймплея

Профилируйте на ранней стадии и почаще

Профилирование важно, потому что оно поможет выяснить, какие оптимизации действительно приведут к большому приросту производительности, а какие являются пустой тратой вашего времени. Благодаря тому, что рендеринг обрабатывается на отдельном чипе (GPU), отрисовка одного кадра занимает в два раза меньше времени (только GPU, а не CPU + GPU). Это означает, что если CPU замедляет работу, оптимизация ваших шейдеров вообще не повысит частоту кадров, и если GPU замедляет работу, не помогут оптимизация физики и скриптов.

Часто бывает так, что разные части игры и разные ситуации работают по разному, так что одна часть игры может привести к 100 миллисекундным кадрам полностью из скрипта, а другая может привести в замедлению игры, потому что в данный момент что нибудь рендерится. Поэтому, если вы собираетесь оптимизировать свою игру, нужно по крайней мере выявить узкие места.

Внутренний Профайлер

Профайлер в Unity в основном используется при ориентации на iOS и Android. См. Руководство по профайлеру для основных инструкций по его использованию.

Внутренний Профайлер

Внутренний профайлер выкидывает текст каждые 30 кадров. Это поможет вам выяснить, какие аспекты вашей игры замедляют ее, будь то физика, скрипты, визуализация, но без множества деталей (например, только название скрипта или визуализации).

См. Встроенный Профайлер для подробной информации о том, как это работает и включается.

Профайлер с рендерингом

Профайлер без рендеринга

Методика адаптации конфигураций под Мобильный клиент

Начиная с версии платформы 8.3.12 в распоряжении разработчиков появилась еще одна технология создания приложений для мобильных устройств – мобильный клиент. Несмотря на схожесть в названиях – «мобильная платформа» и «мобильный клиент», эти две технологии создания приложений для мобильных устройств имеют разное назначение.

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

Мобильный клиент – это аналог тонкого клиента, предназначенный для мобильных устройств. Он позволяет в режиме онлайн получить доступ с мобильных устройств практически ко всей функциональности приложений, которые поддерживают работу через тонкий клиент или веб-клиент. Мобильным клиентом предполагается пользоваться в тех случаях, когда требуется онлайн-доступ к информационной базе с мобильных устройств – например, при использовании сервисов на базе технологии 1С:Fresh. При этом, в отличие от мобильной платформы, данные, введенные на мобильном устройстве, будут сохраняться в общей информационной базе сразу же, без необходимости в дополнительной синхронизации. В мобильном клиенте поддерживается работа системы взаимодействия. Для реализации дополнительной функциональности можно использовать механизм расширений.

Мобильный клиент

Приложение для мобильного клиента является адаптацией прикладного решения, которое поддерживает работу в тонком клиенте или веб-клиенте. Мобильный клиент взаимодействует с информационной базой по протоколу HTTP/HTTPS и, соответственно, может работать только с теми информационными базами, которые опубликованы на веб-сервере.

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

В большинстве случаев адаптация сводится к двум действиям – в модулях на встроенном языке указать функциональность, не поддерживаемую на мобильных устройствах – для этого используется специальная директива препроцессора, и адаптация форм, декларативно описанных в конфигурации, с учетом особенностей их отображения на мобильном устройстве – для этого служат специальные свойства элементов формы (необходимо установить режим совместимости конфигурации не ниже, чем с версией 8.3.7). Также отметим, что на мобильном клиенте недоступны некоторые элементы — диаграммы Ганта, графическая схема, географическая схема, не поддерживаются некоторые операции, например, работа с ZIP-архивами. Отметим, что в процессе адаптации можно расширить функциональность прикладного решения, добавив использование возможностей мобильного устройства – об этом ниже.

Адаптация. Анализ кода

В ходе адаптации необходимо проанализировать код прикладного решения в тех местах, где алгоритмы работы для тонкого клиента и веб-клиента отличаются. Функциональность, которая должна быть доступна на мобильном клиенте указывается директивой препроцессора МобильныйКлиент. Можно начать с того, что везде, где в коде есть директива «#Если НЕ ТонкийКлиент Тогда» и/или «#Если НЕ ВебКлиент Тогда», добавить директиву «И НЕ МобильныйКлиент» чтобы получилось так, как показано ниже.

Далее следует выполнить проверку конфигурации – в конфигураторе выбрать «Главное меню – Конфигурация –Проверка конфигурации», включив опцию «Мобильный клиент».

В тех случаях, когда на сервере требуется получить информацию о том, что сеанс запущен на мобильном клиенте, например, для сбора статистики, тарификации и пр., можно, например, сделать так:

1. Завести булевый параметр сеанса МобильныйКлиент

2. В модуле приложения в блоке #Если МобильныйКлиент устанавливать параметр сеанса в значение Истина, #Если Не МобильныйКлиент – в значение Ложь

3. В серверном коде проверять значение параметра сеанса

Адаптация. Анализ интерфейса

Общие сведения об интерфейсе приложения

Интерфейс мобильного клиента похож на интерфейс приложения, созданного на мобильной платформе. Это накладывает определенные ограничения. Так, например, на экране в один момент времени может отображаться только одна форма, экран имеет относительно небольшую ширину. Как правило, на мобильных устройствах используется только вертикальная прокрутка формы, прокрутка формы по горизонтали не применяется.

Исходя из этих ограничений, мобильный клиент пытается автоматически перестроить форму приложения таким образом, чтобы она поместилась на экране мобильного устройства. В процессе перестройки уменьшается ширина элементов формы для тех элементов, ширина которых в конфигурации задана так, что превышает фактическую ширину экрана на мобильном устройстве. Ширина для таких элементов формируется таким образом, чтобы элемент поместился (по ширине) в текущей ориентации мобильного устройства без горизонтальной прокрутки. Кроме изменения ширины, платформа может попробовать улучшить визуальный вид формы — попытаться уменьшить количество отображаемых элементов формы.

Глобальный командный интерфейс

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

Вызов главного меню приложения осуществляется, в зависимости от модели устройства и ОС или жестом с левой стороны экрана, или с помощью специальной кнопки ?, расположенной в левой части заголовка окна.

Начальная страница

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

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

Кроме формы, на начальной странице может располагаться командный интерфейс основного раздела. Состав командного интерфейса основного раздела и на компьютере, и в мобильном клиенте аналогичен (кроме группы «См. также»). В мобильном клиенте командный интерфейс отображается в виде матрицы кнопок (каждая кнопка связана с одной командой), сгруппированной по страницам. Картинка на кнопке получается из связанной команды. Если команда не обладает настраиваемой картинкой, используется стандартная картинка для данной группы команд.

Команды выводятся так чтобы максимально заполнить рабочую область окна. Группы команд размещается на страницах так, чтобы избежать переноса между страницами, т. е. если после одной группы команд вторая не помещается полностью в оставшееся место, то она начинается с новой страницы. Если все команды не помещаются на экран, то они размещаются на нескольких страницах, которые можно пролистывать.

Адаптация форм

Свойство формы «Сворачивание элементов по важности» управляет описанной выше перестройкой форм. Значение этого свойства «Авто» аналогично значению «Использовать». Для упрощения адаптации у элементов формы (и колонок таблиц, о чем см. ниже) появляется свойство «Важность при отображении». Допустимые значения этого свойства: «ОченьВысокая», «Высокая», «Обычная» и «Низкая». Мобильный клиент обрабатывает значение свойства «Важность при отображении» следующим образом:

  • Более важным элементам отводится больше места на форме, менее важным – меньше, или они просто попадают в сворачиваемую группу (см. ниже)
  • Если более важный элемент расположен под менее важными, и эти менее важные элементы занимают более трех строк формы, то менее важные элементы объединяются и помещаются в сворачиваемую группу. Важно понимать, что здесь и далее важна высота, а не количество элементов. Другими словами, три строки сетки формы могут занимать как три элемента высотой каждый по одной строке, так и один элемент формы, занимающий три строки высоты.
  • Если первым или последним из сворачиваемых элементов является командная панель, то она не сворачивается, так как может относиться к важному элементу.
  • Если более важный элемент расположен внутри иерархии групп или страниц, и при этом в разных местах иерархии над ним расположены менее важные элементы, занимающие более трех строк, в каждом уровне иерархии формируется сворачиваемая группа.
  • Если имеются несколько элементов более высокой важности, то менее важные элементы, находящиеся между ними, помещаются в сворачиваемую группу, если менее важные элементы занимают более трех строк.
  • Менее важные элементы, находящиеся ниже последнего более важного элемента, не сворачиваются.

Если для элемента формы свойство «Важность при отображении» установлено в значение «Авто», то фактическое значение свойства будет определяться по следующим правилам:

  • Значение «ОченьВысокая» для элемента формы, отображающего данные основного реквизита формы (и подчиненные реквизиты).
  • Значение «Высокая», если элемент растягивается по вертикали и является одним из следующих элементов:
    • таблица формы, отображающей динамический список;
    • поле табличного документа;
    • поле диаграммы любого вида и типа;
    • поле форматированного документа;
    • поле HTML-документа.

    • Значение «Высокая», если источником команд для командной панели выступает собственно управляемая форма.
    • Значение важности элемента, который является источником команд для командной панели.
    • Значение важности самого важного элемента в той же группе, что и командная панель, при условии, что для командной панели не установлен источник команд.

    Изменением значений свойства «Важность при отображении» у элементов формы можно добиться желаемого вида формы на экране мобильного устройства.

    Формирование заголовков автоматически сворачиваемых групп

    Если у группы задач есть заголовок, но его отображение отключено, то в случае попадания этой группы в автоматически созданную сворачиваемую группу на мобильном клиенте, текст заголовка используется при формировании заголовка этой автоматически создаваемой сворачиваемой группы. В этом случае элементы группы уже не используются. Это относится и к случаю, когда сворачивается сама группы.

    Мобильный клиент формирует заголовок свертываемой группы по следующему алгоритму:

    • Если свертывается уже существующая группа, то используется заголовок этой группы.
    • Если в свертываемую группу попадает один элемент с заданным заголовком, то используется заголовок этого элемента.
    • Если не подходит ни один из вышеперечисленных пунктов – заголовок формируется соединением, через «,», всех заголовков элементов, входящих в свертываемую группу.

    Отметим, что в ряде случаев может оказаться, что заголовки, которые ранее не отображались, станут «видимыми». Поэтому может потребоваться привести заголовки «в порядок».

    Улучшения в адаптируемости форм

    В ряде конфигураций автоматическая командная панель по разным причинам может отсутствовать – вместо нее используются пользовательские командные панели или группы кнопок формы. Для обеспечения возможности размещения таких объектов (командные панели, группы кнопок и т.п.) в заголовке формы в мобильном интерфейсе у объекта «УправляемаяФорма» добавлено свойство «Состав Командной Панели На Мобильном Устройстве». Данное свойство влияет только на отображение элементов в мобильном клиенте, расположение и свойства элементов в объектной модели формы остаются неизменными. Свойство «Состав Командной Панели На Мобильном Устройстве» представляет собой коллекцию, содержащую элементы формы, которые в мобильном клиенте будут отображаться в командной панели формы, располагаемой в заголовке. На своих «стандартных» местах эти элементы отображаться не будут.

    Если в данный список включен хотя бы один элемент, то в мобильном клиенте в заголовке формы будет отображаться «суррогатная» командная панель, формируемая на основе этого списка. При этом автоматически создаваемая командная панель формы и все ее содержимое отображаться не будет. Местоположение «суррогатной» командной панели не зависит от значения свойства «Положение Командной Панели» — она всегда будет отображаться именно в заголовке формы.

    При использовании коллекции «Состав Командной Панели На Мобильном Устройстве» следует иметь в виду что:

    • В коллекцию нельзя добавить автоматическую командную панель и элементы, расположенные в ней
    • Все группы, помещаемые в заголовочную панель, отображаются как группы вида «ГруппаКнопок». При этом, по возможности, вложенные группы (например, группы вида «Подменю») сохраняют свой вид
    • Если группа формы вида «ОбычнаяГруппа» содержит элементы, которые нельзя поместить в командную панель (например, поля), то они отображаются в форме своих местах

    Свойство «Состав Командной Панели На Мобильном Устройстве» доступно для настройки в конфигураторе и изменения, привносимые этим свойством, отображаются в режиме предварительного просмотра формы при выборе мобильного клиента.

    Свойство «Состав Командной Панели На Мобильном Устройстве» доступно из встроенного языка на сервере и на клиенте. Допустимо размещение в коллекции следующих типов элементов – «КнопкаФормы», и «ГруппаФормы» видов «КоманднаяПанель», «Подменю», «ОбычнаяГруппа» и «ГруппаКнопок». Поддерживаются методы получения количества элементов в коллекции, поиска и получения позиции элемента, добавления, вставки, удаления и перемещения элементов коллекции.

    Адаптация таблиц

    Как мы отметили выше, в мобильной платформе таблица никогда не имеет горизонтальной прокрутки. Поэтому при отображении игнорируется фиксация колонок в таблице и значение свойства «Горизонтальная полоса прокрутки».

    Свойство таблицы управляемой формы «Поведение при сжатии по горизонтали» и свойства «Важность при отображении» колонок этой таблицы управляют отображением колонок, которые не помещаются в видимой части таблицы.

    • Значение «Скрывать элементы по важности» указывает, что колонки таблицы, которые не помещаются на форму, будут скрываться по мере убывания значения свойства колонки «Важность при отображении». Вначале будут скрыты колонки с самой низкой важностью («Очень низкая»), затем — со следующей важностью («Низкая») и т. д. Если есть несколько колонок с одинаковой важностью, то скрытие осуществляется справа налево. Другими словами, чем левее в таблице расположена колонка, тем выше вероятность ее отображения на форме (при прочих равных).
    • Значение «Переносить элементы по важности» указывает, что колонки скрываются по мере убывания важности (аналогично поведению «Скрывать элементы по важности»), а значения скрытых колонок отображаются в отдельной строке, мелким шрифтом, через запятую и с чередованием цветов.
    • Значение «Авто» на мобильном клиенте: аналогично значению «Переносить элементы по важности».

    Таким образом, для того, чтобы максимально повысить вероятность отображения колонки в основной части строки, необходимо присвоить ее свойству «Важность при отображении» значение «ОченьВысокая».

    Работа с данными, связанными с текущей строкой таблиц

    В тех случаях, когда на форме отображаются данные, связанные с текущей строкой таблицы (одной или нескольких), необходимо разделить все данные формы, связанные с текущими данными таблиц таким образом, чтобы одна группа отображала данные только одной таблицы. Для каждой такой группы следует установить свойства «Использование текущей строки» и «Используемая таблица» так, чтобы одна группа могла отображать данные только одной таблицы – в соответствии с рекомендацией размещать связанные данные в разные группы, по количеству используемых таблиц.

    Для таблиц, которые используются в качестве источников данных для вспомогательных данных, следует установить свойство «Использование текущей строки» в значение «Выбор».

    В мобильном клиенте на форме не будет групп, у которых свойство «Использование текущей строки» установлено в значение «Использовать».

    Для того чтобы увидеть связанные данные, необходимо открыть контекстное меню на выбранной строки и выбрать специальную команду, выбор которой откроет окно с данными. Название команды формируется как имя скрытой группы. Если в данной таблице текущие данные отображаются в нескольких группах – название команды будет сформировано из заголовков всех групп, объединенных символом «,».

    Использование «Избранное»

    Один из стандартных интерфейсных механизмов — это «Избранное». Он представляет собой список ссылок, выбранных самим пользователем для быстрого перехода к тем или иным разделам конфигурации, формам объектов информационной базы, а также формам отчетов и обработок. Практически в каждой форме (и ее объектах) существует команда «Добавить в избранное». В мобильном клиенте эта команда доступна через меню, отображаемое вверху экрана справа. Используя механизм “Избранное” пользователь может настроить размещение самых часто используемых команд непосредственно в главном меню приложения (на верхнем уровне). Для этого в настройках списка «Избранное» следует «прикрепить» элемент с помощью переключателя, отображаемого слева от его названия. Прикрепленные элементы будут отображаться в главном меню приложения.

    Существует возможность программного управления списком избранного. Для этого служит объект “Избранное Работы Пользователя”. Его можно получить из общего одноименного хранилища системных настроек. Каждый элемент списка избранного имеет тип “Элемент Избранного Работы Пользователя”. У этого типа есть булево свойство “Важное”. Добавление элемента с установленным значением свойства “Важное” равным “Истина” в список избранного позволит настроить этот список из кода приложения таким образом, что важные для пользователя элементы будут отображаться в верхнем меню приложения.

    Ниже показаны примеры отображения экранов прикладного решения «1С:ERP Управление предприятием 2» на экране компьютера и на мобильном устройстве, в мобильном клиенте.

    Адаптация. Использование возможностей мобильных устройств

    Так как адаптируемое приложение предназначено для работы на мобильном устройстве, в него можно добавить ряд дополнительных возможностей. Перечислим лишь некоторые из них – выполнение звонков из приложения, работа с электронной почтой, работа с SMS/MMS- сообщениями, получение данных о местоположении (координат), сканирование штрих и QR-кодов, запись аудио- и видео и т.п.

    Проверка адаптированного решения

    Проверка в конфигураторе

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

    Проверка на мобильном устройстве

    Для более полной проверки корректной работы адаптированного под мобильный клиент прикладного решения следует выполнить ряд действий.

    Сначала необходимо опубликовать информационную базу на веб-сервере (команда конфигуратора Администрирование – Публикация на веб-сервере). Это требуется для обеспечения работы мобильной платформы с информационной базой по протоколу HTTP/HTTPS. Далее, на мобильном устройстве запускаем файл для установки мобильного клиента (входит в комплект поставки мобильной платформы).

    Далее следует открыть приложение мобильного клиента и добавить в него адаптированное приложение, указав URL веб-сервера и каталог на сервере, в котором опубликована конфигурация.

    После этого следует запустить адаптированное приложение, выполнить ряд типовых сценариев использования приложения, проверить корректность отображения экранных форм и интерфейсных элементах в книжном и альбомном режимах.

    При необходимости следует внести исправления в код приложения и/или атрибуты форм и их элементов и повторить проверку работы адаптированного решения.

    Проверка на устройствах с ОС Android

    Стоит заметить, что в случае работы на устройствах с ОС Android можно обойтись без публикации клиентской части решения и использовать Android Debug Bridge (ADB). Более подробную информацию можно найти в соответствующем разделе документации.

    Публикация решения для внутреннего использования

    Если приложение предназначено для использования только внутри компании, его не обязательно публиковать в магазине приложений – достаточно выполнить следующие действия:

    • Собрать приложение — мобильный клиент для адаптированной конфигурации с требуемой мобильной ОС используя сборщик мобильных приложений
    • Установить приложение у конечных пользователей одним из вариантов:
      • Разместить собранные бинарные файлы на веб-сайте и разослать пользователям ссылки на эти файлы. Для удобства пользователей можно разместить на сайте скрипт, предлагающий к загрузке файл для соответствующей мобильной ОС. В этом случае приложение для iOS должно быть собрано с лицензией разработчика iOS (iOS Developer License). На мобильных устройствах пользователей должны быть сделаны следующие изменения настроек:
        • iOS — Настройки / Основные / Профили и управление устройством и на соответствующем вашему приложению профиле включить опцию «Доверять»
        • Android — в настройках в разделе «Безопасность» (или аналогичном) разрешить установку приложений не из Google Play

        Как встроить возможность обновления приложения

        В случае выбора первого варианта (установка мобильного приложения с веб-сайта) можно реализовать опцию обновления приложения пользователями для случая, когда нужно установить на устройства пользователей приложение, собранное с более новой версией мобильного клиента 1С. Как один из вариантов можно создать в конфигурации константу, в которой будет храниться требуемая версия мобильного клиента. В конфигурацию также надо добавить код (например, в процедуре ПередНачаломРаботыСистемы()), который, в случае работы в мобильном клиенте, сделает следующее:

        1. С помощью свойства СистемнаяИнформация().ВерсияПриложения узнает версию мобильного клиента на устройстве

        2. Сравнит полученную версию со значением константы

        3. В случае несовпадения значений предложит пользователю перейти на сайт обновления (адрес сайта можно закодировать или настроить через константу).

        Заметим, что пользователь может отказаться от перехода на сайт обновления. Способа принудительно обновить мобильное приложение-клиент в случае выбора варианта 1 не существует.

        Вместо выбора конфигураций из мобильного клиента, можно указать адрес информационной базы непосредственно в приложении. Для этого, в сборщике мобильных приложений для создаваемого мобильного приложения на вкладке «Конфигурации» следует указать адрес информационной базы на веб-сервере и собрать приложение. Публикация решения в магазине приложений

        Если приложение предназначено для распространения через магазины приложений – App Store или Google Play, то необходимо выполнить ряд дополнительных действий. Это связано с тем, что мобильный клиент сам по себе является мобильным приложением, способным подключаться к различным прикладным решениям. Но такая функциональность нарушает требования компаний Apple (в первую очередь) и Google – требуется, чтобы опубликованное в магазине приложение значительно не меняло свою функциональность после публикации.

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

        Процедуры сборки и публикации приложений схожие – как для мобильной платформы, так и для мобильного клиента используется единый инструмент – сборщик мобильных приложений – см. https://its.1c.ru/db/v8313doc#bookmark:dev:TI000002058.

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

        Сборщик мобильных приложений – указываем тип конфигурации «Для мобильного клиента»

        Конфигурация – формирование подписи мобильного клиента

        Ключи командной строки конфигуратора

        В случае сборки мобильного приложения из командной строки, существует ключ командной строки пакетного режима запуска конфигуратора MobileClientWriteFile, MobileClientDigiSign. Для ключей командной строки пакетного запуска конфигуратора CheckModules и CheckConfig добавлен параметр -MobileClient. Для ключа командной строки пакетного запуска конфигуратора CheckConfig добавлен параметр -MobileClientDigiSign.

        Готовим конфигурацию Android-приложения с помощью Dynamic Proxy и рефлексии

        Android-разработчик RuStore Анатолий Гусев расскажет, как приготовить систему «холодных» конфигов для большого Android-приложения, построенного на многомодульной архитектуре. Под «холодными» конфигами здесь подразумеваются настройки приложения, которые нужно делать локально на девайсе без необходимости загружать их из сети.

        Зачем нужна конфигурация

        В первую очередь для TBD (trunk-based development — магистральная разработка), когда требуется поставлять фичу под «холодным» переключателем (toggle) не целиком, а быстро и небольшими частями.

        Также пригодится для тестирования. С помощью конфигурации удобно задавать интервалы и длительность фоновых процессов. Например, сократить период синхронизации данных приложения с 24 часов до 15 минут, или задать приложению кастомный endpoint, на котором можно тестировать фичу в разработке.

        Конфигурация в многомодульном проекте

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

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

        data class Configuration( val loggerEnabled: Boolean, val syncInterval: Long, val someFeatureEnabled: Boolean . )

        У этого подхода есть серьёзные минусы:

        1. Бизнес-контекст фич в виде отдельных полей конфига «протекает» в модуль с конфигурацией.
        2. Ситуация, когда все поля конфига содержатся в одной сущности, приводит к тому, что в большом проекте происходит много мелких, но неприятных конфликтов слияния (merge conflict). Это отнимает время и повышает вероятность ошибок.
        3. При удалении фичи легко забыть про удаление связанных с этой фичей полей конфига.

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

        Но взамен мы получим две новые проблемы:

        Проблема 1. Так как конфиг задан интерфейсом, у него должна быть реализация. Конфиги для релиза и отладки отличаются, поэтому нужны две реализации. Это увеличивает количество строк кода и усложняет работу.

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

        • Разложить реализацию по типам сборки внутри модуля implementation , что замедлит сборку.
        • Делать дополнительный Gradle-модуль с отладочной реализацией и подключать его только в отладке. Это увеличит количество шаблонного кода (boilerplate) и приведёт к необходимости создания множества модулей с единственным файлом внутри.

        Конфигурация с помощью Dynamic Proxy

        Начнём с того, что немного сократим количество нужных реализаций конфига с помощью Java Dynamic Proxy. Это механизм, позволяющий «на лету» создать экземпляр переданного интерфейса (и не только интерфейса). С его помощью создадим релизные реализации конфигов.

        Если мы делаем экземпляр конфига «на лету», то откуда взять значения полей конфига? Зададим значения с помощью аннотаций над полями конфига.

        interface GreetingConfig : ConfigMarker

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

        Принцип работы Dynamic Proxy определяет, каким будет интерфейс провайдера конфигов. Мы отдадим провайдеру тип конфига и получим экземпляр класса, его реализующего. Поскольку система предназначена только для конфигов, ограничим типы, с которыми она может работать, маркерным интерфейсом ConfigMarker .

        interface Configs < operator fun get(configType: Class): T >
        class ConfigsImpl @Inject constructor(): Configs < override operator fun get(configType: Class): T < val types = arrayOf(configType) val invocationHandler = ConfigProxyInvocationHandler() return Proxy.newProxyInstance(javaClass.classLoader, types, invocationHandler) as T >>
        internal class ConfigProxyInvocationHandler: InvocationHandler< override fun invoke(instance: Any, method: Method, args: Array?): Any < var valueFromAnnotation:Any? = null when < method.isAnnotationPresent(ConfigStringValue::class.java) -> < valueFromAnnotation = method.getAnnotation(ConfigStringValue::class.java)?.releaseValue >. > return valueFromAnnotation ?: error("All config properties must be annotated") > >

        InvocationHandler — это класс, который обрабатывает вызовы всех методов и полей созданного прокси. При обращении к геттерам конфига нужно проверить наличие аннотации с релизным значением, и, вытащив из аннотации это значение, вернуть его. Если было обращение к не аннотированному свойству, то выкидываем исключение.

        Подготовка реализации

        Теперь наша система работоспособна. Для релизной сборки этого достаточно. Подготовим реализацию для отладочной сборки с более сложной логикой.

        Сначала определим, как будут храниться отладочные конфиги. Наиболее приемлемый компромисс: собрать отладочные реализации конфигов в отдельном Gradle-модуле, но только в одном — чтобы не плодить сущности. Это будет тот же модуль, где лежит реализация отладочной части системы конфигов.

        Отладочные конфиги сделаем в виде написанного вручную data -класса.

        data class GreetingDebugConfig( override val target: String = "Test", ) : GreetingCon

        Для хранения конфигов в отладке используем память в Map . Ключом будет класс интерфейса конфига, а значением — отладочная реализация.

        class ConfigInMemoryDataSource @Inject constructor() < private val configs: MutableMap, ConfigMarker> = mutableMapOf() fun get(configType: Class): T = configs[configType] as? T ?: error("No debug config") . >

        Нужно учесть, что набор конфигов, с которым работает приложение, создаётся на самых ранних этапах инициализации приложения и в процессе работы не меняется. Любые правки конфигов должны сопровождаться рестартом.

        После подготовки базовой части системы, дополним её более сложными фичами. Сделаем отладочный экран для редактирования конфигов. Для этого определим, как будет выглядеть State экрана.

        data class ConfigState( val configValues: Map, val expanded: Boolean = false, ) open class ConfigProperty( val displayName: String, val fullName: String, )

        Для каждого типа, поддерживаемого системой конфигов, выберем отдельный подкласс ConfigProperty .

        class ConfigBoolProperty(displayName: String, fullName: String, val value: Boolean) :ConfigProperty(displayName, fullName) class ConfigIntProperty(displayName: String, fullName: String, val value: Int) :ConfigProperty(displayName, fullName) class ConfigLongProperty(displayName: String, fullName: String, val value: Long) : ConfigProperty(displayName, fullName) class ConfigStringProperty(displayName: String, fullName: String, val value: String) : ConfigProperty(displayName, fullName)

        Это упростит редактирование на экране. А чтобы не вынуждать разработчика при изменениях конфигов лезть ещё и в UI отладочного экрана, сгенерируем State с помощью рефлексии на основе всех конфигов приложения.

        Вот так выглядит маппинг в State .

        class ConfigStateMapper @Inject constructor() < fun map(configType: Class, config: ConfigMarker): ConfigState < val properties = config.javaClass.kotlin.memberProperties val propertiesData = properties.associate < property ->val propertyValue = property.getter.call(config) val fullName = "$.$" fullName to toPropertyModel(fullName, property, propertyValue) > return ConfigState(propertiesData) > private fun toPropertyModel(fullName: String, property: KProperty1, propertyValue: Any?): ConfigProperty = when < isPropertyAssignableFrom(property, Boolean::class.java) ->ConfigBoolProperty(property.name, fullName, propertyValue as Boolean) isPropertyAssignableFrom(property, Int::class.java) -> ConfigIntProperty(property.name, fullName, propertyValue as Int) isPropertyAssignableFrom(property, Long::class.java) -> ConfigLongProperty(property.name, fullName, propertyValue as Long) else -> ConfigStringProperty(property.name, fullName, propertyValue.toString()) > private fun isPropertyAssignableFrom(property: KProperty1, type: Class, ): Boolean = property.javaField?.type?.isAssignableFrom(type) ?: false >

        В ходе работы с экраном пользователь модифицирует State . Чтобы отредактированный конфиг применился, нужно как-то хранить изменения. Это касается только изменённых полей конфига, которые состоят из пар «ключ-значение». Ключом считается полное имя класса конфига и имя поля, а значением — отредактированное значение.

        Сохраним пары в preferences . В этом формате проще понять, как именно настроено приложение, если возникнут проблемы с конфигурацией.

        Чтобы найти все изменения по сравнению с дефолтной конфигурацией, возьмём список конфигов с дефолтными значениями и сверим с текущим State экрана.

        Применим сохранённые поля конфига при запуске. Для этого в процессе инициализации нужно получить список дефолтных конфигов, пройтись по нему и с помощью рефлексии изменить значения отредактированных полей.

        private fun applyToConfig(configKey: Class, config: ConfigMarker, changed: Map) < val properties = config.javaClass.kotlin.memberProperties properties.forEach < property ->val fullName = "$.$" if (changed.contains(fullName)) < property.javaField?.isAccessible = true when < isPropertiesAssignableFrom(property, Boolean::class.java) -> < property.javaField?.set(config, changed[fullName]?.toBoolean()) >. > > > >

        Основные моменты реализации отладочного экрана готовы. Чтобы не задумываться о том, где можно использовать конфиги, а где нет, используем библиотеку androidx.startup и вынесем инициализацию конфигов на этап до старта приложения.

        internal class ConfigInitializer : Initializer  < @Inject internal lateinit var initConfigsUseCase: InitConfigsUseCase override fun create(context: Context) < //inject dependency initConfigsUseCase() >>

        Так как в момент, когда инициализатор отработает графы зависимостей, основного приложения ещё нет, сделаем ConfigInMemoryDataSource синглтоном. Это позволит воспользоваться инициализированными конфигами уже в приложении.

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

        Решение проблем при разработке под Android

        Unity не удаётся установить ваше приложение на ваше устройство

        1. Убедитесь, что ваш компьютер видит ваше устройство и может взаимодействовать с ним. Для деталей см. Публикация сборок.
        2. Проверьте консоль Unity на наличие сообщений об ошибках. Это часто помогает в определении проблемы.

        Если у вас появляется ошибка “Unable to install APK, protocol failure” во время сборки, то это значит, что ваше устройство подключено через USB-порт с низким питанием (возможно порт на клавиатуре или ещё на какой-нибудь периферии). Если такое случается, то попробуйте подсоединить устройство в USB порт на самом компьютере.

        Ваше приложение падает сразу после запуска.

        1. Убедитесь, что вы не пытаетесь использовать NativeActivity с устройствами, которые это не поддерживают.
        2. Попробуйте убрать все нативные плагины, что у вас есть.
        3. Попробуйте отключить stripping.
        4. Используйте adb logcat чтобы получить отчёт о крахе с вашего устройства.

        Building DEX Failed

        Это ошибка, которая выдаёт сообщение, вроде следующего:-

        Building DEX Failed! G:\Unity\JavaPluginSample\Temp/StagingArea> java -Xmx1024M -Djava.ext.dirs="G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/" -jar "G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/dx.jar" --dex --verbose --output=bin/classes.dex bin/classes.jar plugins Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine. 

        Обычно это вызвано неверной версией Java на вашем компьютере. Обновление Java до последней версии обычно решает проблему.

        Приложение падает через несколько секунд после начала проигрывания видео.

        Убедитесь, что Settings->Developer Options->Don’t keep activities не включено на вашем телефоне. Проигрыватель видео — это отдельное приложение и поэтому обычное игровое приложение будет закрыто, если проигрыватель видео включён.

        Моя игра закрывается, когда я жму кнопку сна

        Измените тег activity в файле AndroidManifest.xml так , чтобы он содержал тег android:configChanges , сделайте это таким образом, как описано здесь.

        Пример тега activity может выглядеть, например, вот так:-

Добавить комментарий

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