При разработке мобильных приложений и управляемых форм в платформе «1С:Предприятие» разработчики часто сталкиваются с ситуацией: в коде процедуры сначала меняется свойство Видимость элемента формы (например, выводится надпись «Идет обмен...»), а затем запускается длительный сетевой или вычислительный процесс. Однако на экране надпись появляется только после завершения всей работы, либо интерфейс «зависает» и сразу отображает конечный результат.
В этой статье мы разберем причину такого поведения клиентского контекста 1С и проанализируем, как правильно организовать управление интерфейсом при длительных операциях.
Проанализируем механику работы управляемого интерфейса платформы 1С. Клиентский контекст (включая мобильную платформу) является однопоточным. Это означает, что пользовательский интерфейс и ваш клиентский код выполняются в едином потоке обработки событий.
Когда в процедуре устанавливается значение Элементы.Обмен.Видимость = Истина;, платформа не перерисовывает экран моментально. Она лишь регистрирует изменение свойства в оперативной памяти. Фактическая перерисовка формы (отрисовка операционной системой Android или iOS) происходит только тогда, когда процедура полностью завершает свою работу и управление возвращается в цикл обработки событий платформы.
Если сразу после изменения видимости начинается тяжелый синхронный вызов (например, обмен данными по сети или пошаговая синхронизация), главный поток блокируется. Пользователь видит застывший экран, а все визуальные изменения отображаются скопом уже после завершения процедуры.
Разберем по шагам основной способ решения этой задачи. Чтобы платформа успела передать команды перерисовки графической подсистеме операционной системы, нам необходимо разбить выполнение кода на два этапа и вернуть управление циклу событий между ними.
Для этого применяется метод ПодключитьОбработчикОжидания с однократным вызовом.
Рассмотрим, как изменить исходный код. В кнопке действия мы только меняем интерфейс и регистрируем однократный вызов следующей процедуры:
&НаКлиенте
Процедура НачатьРаботу(Команда)
// 1. Меняем видимость элементов
Элементы.Приветствие.Видимость = Ложь;
Элементы.Обмен.Видимость = Истина;
// 2. Подключаем однократный обработчик ожидания с минимальным интервалом
ПодключитьОбработчикОжидания("ВыполнитьОбменИОбработку", 0.1, Истина);
КонецПроцедуры
После выполнения процедуры НачатьРаботу управление сразу же возвращается платформе. За доли секунды паузы платформа успевает перерисовать форму и отобразить элемент Обмен на экране мобильного устройства. Затем автоматически срабатывает подключенная процедура:
&НаКлиенте
Процедура ВыполнитьОбменИОбработку()
Если МП_ОбменСервер.ПроверитьПодключение() Тогда
Если МП_ОбменСервер.ВыполнитьСинхронизациюПошагово() Тогда
Элементы.Обмен.Видимость = Ложь;
Сообщить("Синхронизация прошла успешно!");
Иначе
Элементы.Обмен.Видимость = Ложь;
Сообщить("При синхронизации были ошибки!");
КонецЕсли;
Элементы.Работа.Видимость = Истина;
ОбработатьСтраницуЗаданий();
МП_СлужебныйКлиент.ПроверкаНеЗавершенныхАктов();
МП_ГеопозиционированиеКлиент.ВключитьАвтоЗаписьКоординат();
Иначе
Элементы.Обмен.Видимость = Ложь;
Сообщить("Неверные данные подключения! Выполните настройку еще раз.");
Элементы.Подключение.Видимость = Истина;
ЗаполнитьОпцииПодключения();
КонецЕсли;
КонецПроцедуры
Посмотрим на другие варианты архитектурных решений для мобильной платформы и управляемых форм:
Асинх / Ждать): Если сетевые функции платформы поддерживают асинхронную работу, рекомендуется переводить синхронизацию на асинхронные процедуры. В точках ожидания с ключевым словом Ждать контроль временно возвращается платформе, что позволяет GUI оставаться отзывчивым.ФоновыеЗадания): Для длительных процессов обмена или сложных расчетов лучшей практикой является вынос логики в фоновое задание. На клиенте включается индикатор загрузки, запускается фоновая задача, а состояние проверяется периодически через обработчик ожидания. Это полностью защищает мобильное приложение от принудительного закрытия операционной системой по таймауту (ANR / Watchdog).Состояние(): В обычных формах часто использовался вызов Состояние(...), однако на мобильной платформе во время длительного синхронного вызова этот метод также может не успевать обновлять текст из-за особенностей графического стека мобильных ОС.Резюме: В управляемом интерфейсе 1С не существует метода принудительной перерисовки формы вроде старого ОбработатьСобытия(). Единственный надежный способ отобразить изменения элементов перед длительной операцией — отдать управление платформе с помощью ПодключитьОбработчикОжидания или асинхронных вызовов.