При разработке мобильных приложений на платформе «1С:Предприятие» часто возникает необходимость интеграции с торговым оборудованием, например, со встроенными или внешними сканерами штрихкодов. Для этого используется механизм внешних компонент. Однако разработчики часто сталкиваются с неприятным поведением системы: при попытке инициализировать драйвер мобильное приложение начинает обращаться по сети к веб-серверу публикации (Apache или IIS) и скачивать оттуда файлы библиотек (.so и .apk). Если в этот момент сервер недоступен или мобильное устройство работает в офлайн-режиме, подключение драйвера завершается ошибкой.
В этой статье мы подробно разберем, почему мобильная платформа ведет себя подобным образом, проанализируем внутренние механизмы публикации и рассмотрим несколько эффективных способов решения этой проблемы, сохранив возможность динамического обновления конфигурации.
Давайте проанализируем ситуацию под капотом мобильной платформы. Когда мы создаем макет с типом «Внешняя компонента» и загружаем туда ZIP-архив драйвера (например, драйвер 1С для сканера штрихкода), платформа стремится оптимизировать процесс доставки конфигурации на мобильные устройства.
При публикации мобильного приложения на веб-сервере происходит следующее:
1Cv8.1CM формируется без тяжелых бинарных файлов внешних компонент, чтобы минимизировать его размер (он остается весом около 2-3 МБ). Это ускоряет его загрузку на устройство..so для разных архитектур процессоров Android и вспомогательные файлы .apk) извлекаются платформой и помещаются в каталог публикации в специально созданную структуру папок, например: /ИмяПубликации/Android/arm/.1cema.xml прописываются ссылки на эти внешние ресурсы.Когда на мобильном устройстве выполняется код подключения компоненты:
Результат = ПодключитьВнешнююКомпоненту("ОбщийМакет.Драйвер1ССканерШтрихкода", "MobileBarcodeScanner", ТипВнешнейКомпоненты.Native);
Мобильный клиент обращается к файлу манифеста, видит ссылки на внешние файлы на веб-сервере и начинает скачивать их по протоколу HTTP/HTTPS. Если веб-сервер выключен, заблокирован брандмауэром или у устройства просто отсутствует интернет-соединение, инициализация прерывается ошибкой подключения драйвера.
Поведение кэширования внешних компонент сильно зависит от версии мобильной платформы «1С». В старых версиях (например, ветки 8.3.9 – 8.3.11) механизмы кэширования работали нестабильно. Мобильное приложение могло повторно обращаться к веб-серверу при каждом запуске сессии или инициализации компоненты, игнорируя уже скачанные ранее локальные файлы.
Начиная с версий платформы 8.3.12 и 8.3.13, логика работы с внешними компонентами была существенно доработана:
ПодключитьВнешнююКомпоненту() приложение действительно обратится к веб-серверу публикации и скачает необходимые библиотеки.Рекомендация: Обновите мобильную платформу и мобильный клиент до актуальных версий (не ниже 8.3.13). Это решит проблему повторных сетевых запросов при стабильной работе приложения в офлайн-режиме.
Если специфика вашего проекта требует стопроцентной гарантии того, что приложение никогда не пойдет на веб-сервер за файлами компоненты, но при этом вам необходимо сохранить схему обновления через конфигурационный файл 1cema.xml (без сборки полноценного APK), мы можем прибегнуть к обходному пути. Изменим тип хранения драйвера в конфигурации.
Разберем этот метод по шагам:
// Получаем архив с драйвером из двоичных данных
ДвоичныеДанныеДрайвера = ПолучитьОбщийМакет("ДрайверСканераДвоичныеДанные");
// Помещаем во временное хранилище
АдресХранилища = ПоместитьВоВременноеХранилище(ДвоичныеДанныеДрайвера);
// Подключаем компоненту из временного хранилища
Результат = ПодключитьВнешнююКомпоненту(АдресХранилища, "MobileBarcodeScanner", ТипВнешнейКомпоненты.Native);
Если Результат Тогда
// Инициализируем объект драйвера для работы
ОбъектДрайвера = Новый("AddIn.MobileBarcodeScanner.BarcodeScanner");
Иначе
Сообщить("Не удалось подключить драйвер сканера из двоичных данных!"); КонецЕсли;
Почему это работает? При использовании макета типа «Двоичные данные» мобильная платформа не извлекает файлы драйвера в отдельную папку публикации на веб-сервере. Весь архив компилируется непосредственно внутрь файла конфигурации 1Cv8.1CM. Да, размер загружаемой конфигурации увеличится на размер архива компоненты (обычно на несколько мегабайт), но при этом при первом запуске и обновлении клиент скачает один монолитный файл конфигурации, а подключение драйвера будет происходить локально без единого сетевого запроса к Apache.
Если ваше приложение готово к релизу и переведено в режим промышленной эксплуатации (продакшн), наиболее правильным и надежным решением будет отказаться от запуска конфигурации через стандартную мобильную платформу разработчика 1С и собрать полноценный собственный файл .apk с помощью Сборщика мобильных приложений 1С.
Рассмотрим преимущества этого подхода подробнее:
ПодключитьВнешнююКомпоненту().Если вас беспокоит вопрос регулярного обновления конфигурации у клиентов, то вместо механизма 1cema.xml вы можете настроить собственный локальный веб-сервер дистрибуции (аналог корпоративного Google Play) или воспользоваться облачными MDM-системами для автоматического обновления APK на устройствах пользователей при выпуске новых релизов.
Если вы все же решили использовать динамическую загрузку внешних компонент из публикации (Решение 1), обязательно убедитесь, что ваш веб-сервер корректно отдает файлы библиотек мобильным устройствам. По умолчанию Apache или IIS могут блокировать отдачу файлов с неизвестными расширениями, такими как .so (библиотеки C++) или .apk.
Проанализируем настройку веб-сервера Apache. В конфигурационном файле mime.types обязательно должна быть прописана директива, которая сопоставляет расширения компонентов с бинарным потоком передачи данных:
application/octet-stream so apk dylib a
Без этой настройки даже при доступном веб-сервере мобильное приложение не сможет скачать компоненту и будет возвращать ошибку инициализации, так как сервер будет отдавать ошибку HTTP 403 или HTTP 404 при попытке скачать файлы драйвера.