Как обновить пользовательский интерфейс во время работы?
В процессе изучения kotlin и android studio решил сделать, казалось бы, банальную вещь: таймер. Всего-то вот тебе button, вот тебе textView, нажал на кнопку, цикл for запустился и знай себе подставляет новое значение в textView, засыпает на секунду и по новой. Но узнал маленький нюанс: все элементы пользовательского интерфейса отказываются обновляться до завершения onResume (по крайней мере, это то, как это выглядит). И поэтому такой код:
override fun onResume() < super.onResume() for(i in 1..10) < bindingClass.textView.text = i.toString() Thread.sleep(1000) >>
Приводит лишь к тому, что приложение будто зависает на 10 секунд, а потом сразу показывает «10» на экране. Пробовал запустить в отдельной сопрограмме через runBlocking < launch <>> , но результат тот же.
Какой самый оптимальный способ добиться нужного результата? И неужели обновлять пользовательский интерфейс во время работы приложения настолько редкая задача, что в котлине не добавили какой-нибудь заготовленный способ это сделать? По крайней мере, мне не удалось его найти
- Вопрос задан более двух лет назад
- 720 просмотров
Настройка среды
Прежде чем приступить к созданию своего первого приложения для работы как на iOS, так и на Android, начните с настройки среды для Kotlin Multiplatform Mobile разработки:

- Если вы собираетесь работать с общим кодом или кодом, специфичным для Android, вы можете работать на любом компьютере с операционной системой, поддерживаемой Android Studio. Если вы также хотите написать код, специфичный для iOS, и запускать приложение на моделируемом или реальном устройстве, используйте Mac с macOS. Работать с iOS в других операционных системах, таких как Microsoft Windows, нельзя. Это связано с требованием Apple.
- Установите Android Studio 4.2 или 2020.3.1 Canary 8 или выше. Вы будете использовать Android Studio для создания своих мультиплатформенных приложений и запуска их на имитируемых или аппаратных устройствах.
- Если вам нужно написать код для iOS и запускать приложения, установите Xcode версии 11.3 или выше. Большую часть времени Xcode будет работать в фоновом режиме. Вы будете использовать его для добавления кода на Swift или Objective-C в свое приложение.
- Убедитесь, что у вас установлен совместимый плагин Kotlin. В Android Studio выберите Tools | Kotlin | Configure Kotlin Plugin Updates и проверьте текущую версию плагина Kotlin. При необходимости обновите до последней Stable версии.
- Установите плагин Kotlin Multiplatform Mobile. В Android Studio выберите Preferences | Plugins, найдите плагин Kotlin Multiplatform Mobile в Marketplace и установите его. Посмотрите Kotlin Multiplatform Mobile plugin release notes.
© 2015—2024 Open Source Community
Пошаговое руководство. Привязка библиотеки Kotlin для Android
В настоящее время рассматривается возможность использования настраиваемых привязок на платформе Xamarin. Примите участие в этом опросе, чтобы помочь определить дальнейшие направления разработки.
Xamarin позволяет разработчикам мобильных приложений создавать собственные кросс-платформенные мобильные приложения с использованием Visual Studio и C#. Вы можете использовать готовые компоненты пакета SDK для платформы Android, но во многих случаях вам также может понадобиться использовать сторонние пакеты SDK, написанные для этой платформы, и Xamarin позволяет сделать это с помощью привязок. Чтобы внедрить стороннюю платформу Android в приложение Xamarin.Android, необходимо создать привязку Xamarin.Android, чтобы использовать ее в приложениях.
Платформа Android, а также ее машинные языки и средства постоянно развиваются. К примеру, недавно введен язык Kotlin, который, в конечном итоге, заменяет Java. Существует ряд сторонних пакетов SDK, которые уже перенесены с Java на Kotlin, и это ставит перед нами новые задачи. Несмотря на то, что процесс привязки Kotlin аналогичен этому процессу на Java, он требует дополнительных шагов и параметров конфигурации для успешной сборки и запуска в рамках приложения Xamarin.Android.
Цель этого документа — описать общий подход для подготовки такого сценария и предоставить подробные пошаговые инструкции с простым примером.
Фон
Kotlin выпущен в феврале 2016 г. и представлен в качестве альтернативы стандартному компилятору Java в Android Studio к 2017 г. Позднее в 2019 г. корпорация Google объявила о том, что язык Kotlin стал предпочтительным языком для разработчиков приложений Android. Общий подход на основе привязки аналогичен процессу привязки регулярных библиотек Java, но при использовании в Kotlin необходимы несколько важных специальных шагов.
Предварительные требования
Для выполнения данного пошагового руководства требуется:
- Android Studio
- Visual Studio для Mac
- Декомпилятор Java
Сборка собственной библиотеки
Первым шагом является сборка собственной библиотеки Kotlin с помощью Android Studio. Библиотека обычно предоставляется сторонним разработчиком или доступна в репозитории Google Maven и других удаленных репозиториях. Например, в этом учебнике создается привязка для библиотеки Kotlin Bubble Picker:


- Скачайте исходный код из GitHub для библиотеки и распакуйте его в локальной папке Bubble-Picker.
- Запустите Android Studio, выберите пункт меню Open an existing Android Studio project (Открыть существующий проект Android Studio) и укажите локальную папку Bubble-Picker:
- Убедитесь, что Android Studio не устарела, в том числе Gradle. Исходный код можно успешно собрать в Android Studio версии 3.5.3, Gradle версии 5.4.1. Инструкции по обновлению Gradle до последней версии можно найти здесь.
- Убедитесь, что установлен обязательный пакет SDK для Android. Исходный код требует пакет SDK для Android версии 25. Откройте меню Диспетчер пакетов SDK для инструментов>, чтобы установить компоненты пакета SDK.
- Обновите и синхронизируйте главный файл конфигурации build.gradle, расположенный в корне папки проекта:
- Задайте параметру версии Kotlin значение 1.3.10.
buildscript
allprojects < repositories < jcenter() maven < url "https://maven.google.com" >> >

После обновления файла конфигурации он не синхронизирован, и в Gradle будет отображаться кнопка Sync Now (Синхронизировать сейчас), нажмите ее и дождитесь завершения процесса:
Совет Кэш зависимостей Gradle может быть поврежден, это иногда происходит после истечения времени ожидания сетевого подключения. Повторно скачайте зависимости и синхронизируйте проект (требуется подключение к сети).
Совет У процесса сборки Gradle (управляющей программ) может быть поврежденное состояние. Остановка всех управляющих программ Gradle может решить эту проблему. Остановите процессы сборки Gradle (требуется перезапуск). В случае повреждения процессов Gradle можно также закрыть интегрированную среду разработки, а затем завершить все процессы Java.
Совет Возможно, ваш проект использует сторонний подключаемый модуль, который несовместим с другими подключаемыми модулями в проекте или версии Gradle, запрошенной проектом.


Файл AAR — это архив Android, который содержит скомпилированный исходный код и ресурсы Kotlin, необходимые Android для выполнения приложения с использованием этого пакета SDK.
Подготовка метаданных
Вторым шагом является подготовка файла преобразования метаданных, который используется Xamarin.Android для создания соответствующих классов C#. Проект привязки Xamarin.Android будет обнаруживать все собственные классы и члены из заданного архива Android с последующим созданием файла XML с соответствующими метаданными. Затем созданный вручную файл преобразования метаданных необходимо применить к ранее созданному базовому плану, чтобы создать окончательный файл XML определения, используемый для создания кода C#.
Метаданные используют синтаксис XPath и используются генератором привязок, чтобы повлиять на создание сборки привязки. В статье Метаданные привязок Java приведены дополнительные сведения о преобразованиях, которые могут быть применены:
-
Создайте пустой файл Metadata.xml:

- У собственной библиотеки Kotlin есть две зависимости, которые вам не нужно предоставлять в коде C#, задайте два преобразования, чтобы полностью их игнорировать. Важно отметить, что собственные члены не будут удалены из результирующего двоичного файла, только не будут создаваться классы C#. Декомпилятор Java можно использовать для определения зависимостей. Запустите средство и откройте созданный ранее файл AAR, в результате чего будет показана структура архива Android со всеми зависимостями, значениями, ресурсами, манифестами и классами: Преобразования для пропуска обработки этих пакетов определяются с помощью инструкций XPath:
BackgroundColor BackgroundColor
public open fun fooUIntMethod(value: UInt) : String < return "fooUIntMethod$" >
Этот код компилируется в следующий байтовый код Java:
@NotNull public String fooUIntMethod-WZ4Q5Ns(int value)
Более того, связанные типы, такие как UIntArray, UShortArray, ULongArray, UByteArray , также затрагиваются Kotlin. Имя метода изменяется и включает в себя дополнительный суффикс, а параметры изменяются на массив элементов подписанных версий тех же типов. В примере ниже параметр типа UIntArray преобразуется автоматически в int[] , а имя метода изменяется с fooUIntArrayMethod на fooUIntArrayMethod—ajY-9A . Имя метода обнаруживается средствами Xamarin.Android и формируется как допустимое имя метода:
public open fun fooUIntArrayMethod(value: UIntArray) : String < return "fooUIntArrayMethod$" >
Этот код компилируется в следующий байтовый код Java:
@NotNull public String fooUIntArrayMethod--ajY-9A(@NotNull int[] value)
Чтобы дать ему понятное имя, в Metadata.xml можно добавить следующие метаданные, которые обновят имя на исходное, определенное в коде Kotlin:
fooUIntArrayMethod
public open fun fooGenericMethod(value: T) : String < return "fooGenericMethod$" >
После создания привязки Xamarin.Android метод предоставляется в C# следующим образом:
[Register ("fooGenericMethod", "(Ljava/lang/Object;)Ljava/lang/String;", "GetFooGenericMethod_Ljava_lang_Object_Handler")] [JavaTypeParameters (new string[] < "T" >)] public virtual string FooGenericMethod (Java.Lang.Object value);
Универсальные шаблоны Java и Kotlin не поддерживаются привязками Xamarin.Android, поэтому создается обобщенный метод C# для доступа к универсальному API. В качестве обходного решения можно создать библиотеку-оболочку Kotlin и предоставить необходимые API строго типизированным способом без универсальных шаблонов. Кроме того, можно создавать вспомогательные приложения на C# для решения проблемы таким же образом с помощью строго типизированных API.
Совет При преобразовании метаданных к созданной привязке можно применить любые изменения. В статье Привязка библиотеки Java подробно объясняется, как создаются и обрабатываются метаданные.
Сборка библиотеки привязки
Следующим шагом является создание проекта привязки Xamarin.Android с помощью шаблона привязки Visual Studio, добавления необходимых метаданных, собственных ссылок и последующая сборка проекта для создания готовой к использованию библиотеки:

- Откройте Visual Studio для Mac и создайте проект библиотеки привязки Xamarin.Android, присвойте ему имя, в этом случае — testBubblePicker.Binding, и завершите работу мастера. Шаблон привязки Xamarin.Android расположен по следующему пути: Библиотека привязки библиотеки > Android>: В папке Transformations есть три основных файла преобразования:
- Metadata.xml — позволяет вносить изменения в окончательный API, например изменять пространство имен созданной привязки.
- EnumFields.xml — содержит сопоставление константами int Java и перечислениями C#.
- EnumMethods.xml — позволяет изменять параметры метода и типы возвращаемых значений с целочисловых констант Java на перечисления C#.
Сохраните пустые файлы EnumFields.xml и EnumMethods.xml, а затем обновите Metadata.xml для определения преобразований.


Совет Из-за ограничения Xamarin.Android средства привязки можно добавить только в один архив Android (AAR) для каждого проекта привязки. Если необходимо добавить несколько файлов AAR, требуется несколько проектов Xamarin.Android, по одному на каждый AAR. Если бы мы столкнулись с этим в этом пошаговом руководстве, то предыдущие четыре действия этого шага надо было бы повторить для каждого архива. В качестве альтернативного варианта можно вручную объединить несколько архивов Android в один, и в результате можно использовать один проект привязки Xamarin.Android.
Использование библиотеки привязки
Последним шагом является использование библиотеки привязки Xamarin.Android в приложении Xamarin.Android. Создайте проект Xamarin.Android, добавьте ссылку на библиотеку привязки и визуализируйте пользовательский интерфейс Bubble Picker:
- Создайте проект Xamarin.Android. Используйте приложение Android > для android > в качестве отправной точки и выберите последняя и самая большая версия в качестве целевой платформы, чтобы избежать проблем с совместимостью. Все последующие шаги предназначены для этого проекта:

- Добавьте ссылку на проект в проект привязки или добавьте ссылку на созданную ранее библиотеку DLL:

- Добавьте ссылку на пакет Xamarin.Kotlin.StdLib NuGet, который вы ранее добавили в проект привязки Xamarin.Android. Этот пакет поддерживает любые специальные типы Kotlin, которые должны обрабатываться в среде выполнения. Без этого пакета приложение можно скомпилировать, но произойдет сбой во время выполнения:

- Добавьте элемент управления BubblePicker в макет Android для MainActivity . Откройте файл testBubblePicker/Resources/layout/content_main.xml и добавьте узел элементов управления BubblePicker в виде последнего элемента корневого элемента управления RelativeLayout:
protected override void OnCreate(Bundle savedInstanceState) < . var picker = FindViewById(Resource.Id.picker); picker.BubbleSize = 20; picker.Adapter = new BubblePickerAdapter(); picker.Listener = new BubblePickerListener(picker); . >
BubblePickerAdapter и BubblePickerListener — это два класса, создаваемые с нуля. Они обрабатывают данные пузырьков и управляют взаимодействием:
public class BubblePickerAdapter : Java.Lang.Object, IBubblePickerAdapter < private List_bubbles = new List(); public int TotalCount => _bubbles.Count; public BubblePickerAdapter() < for (int i = 0; i < 10; i++) < _bubbles.Add($"Item "); > > public PickerItem GetItem(int itemIndex) < if (itemIndex < 0 || itemIndex >= _bubbles.Count) return null; var result = _bubbles[itemIndex]; var item = new PickerItem(result); return item; > > public class BubblePickerListener : Java.Lang.Object, IBubblePickerListener < public View Picker < get; >public BubblePickerListener(View picker) < Picker = picker; >public void OnBubbleDeselected(PickerItem item) < Snackbar.Make(Picker, $"Deselected: ", Snackbar.LengthLong) .SetAction("Action", (Android.Views.View.IOnClickListener)null) .Show(); > public void OnBubbleSelected(PickerItem item) < Snackbar.Make(Picker, $"Selected: ", Snackbar.LengthLong) .SetAction("Action", (Android.Views.View.IOnClickListener)null) .Show(); > >

Поздравляем! Вы успешно создали приложение Xamarin.Android и библиотеку привязок, которая использует библиотеку Kotlin.
Теперь у вас должно быть базовое приложение Xamarin.Android, которое использует собственную библиотеку Kotlin через библиотеку привязки Xamarin.Android. В этом пошаговом руководстве намеренно используется простой пример для выделения основных понятий. В реальных сценариях, скорее всего, потребуется предоставить большее количество API и применить к ним преобразования метаданных.
Связанные ссылки
- Android Studio
- Установка Gradle
- Visual Studio для Mac
- Декомпилятор Java
- Библиотека Kotlin BubblePicker
- Привязка библиотеки Java
- XPath
- Метаданные привязки Java
- Xamarin.Kotlin.StdLib NuGet
- Репозиторий примеров проектов
Обновление версий
Своевременное обновление версий Gradle и его плагинов гарантирует, что вы используете наиболее актуальную версию без багов и уязвимостей.
Также с выходом новых обновлений появляются новые функции, которые, возможно, понадобятся в проекте.
Gradle
Мы используем Gradle Wrapper как обертку, которая автоматизирует процесс установки нужной версии Gradle.
Чтобы поменять версию Gradle в вашем проекте, необходимо перейти в директорию gradle/wrapper и открыть файл его настроек gradle-wrapper.properties :
# . # URL-адрес для загрузки дистрибутива Gradle distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip # .
Каталог с возможными версиями Gradle вы можете найти тут.
Gradle придерживается такого подхода к версионированию, при котором апдейты минорных версий не нарушают обратную совместимость. При обновлении же мажорных версий, например Gradle 6.9.1 ~> 7.0.2 , есть высокая вероятность, что что-то будет несовместимо, поэтому такие апдейты надо делать аккуратно и проверять, что будет с обеими платформами.
Plugins
Что делать если Android Studio предложила обновить Android Gradle Plugin (AGP) или Kotlin Gradle Plugin? Какие плагины и зависимости можно обновлять без последствий?
Kotlin и Android
В принципе, вы можете обновлять все плагины и зависимости, поддерживающие семантическое версионирование, но на минорных апдейтах, чтобы не нарушалась обратная совместимость.
С ноября 2020 года Android Gradle Plugin поддерживает семантическое версионирование, поэтому при обновлении AGP с версии 7.0 на версию 7.1 ничего сломаться не должно.
Kotlin поддерживает немного другой вид версионирования, о котором вы можете прочитать тут.
Например, если в вашем проекте используется Kotlin Multiplatform Plugin:
plugins kotlin("multiplatform") version "1.4.21" >
то при смене feature версии 1.4.21 ~> 1.5.21 нужно проверить компиляцию обеих платформ и работу кода во время выполнения. Также скорее всего придется обновлять и версии библиотек на те, которые поддерживают новую версию.
А при смене incremental ( 1.5.21 -> 1.5.30 ) и bugfix ( 1.5.20 -> 1.5.21 ) версий обратная совместимость сохраняется и проблем быть не должно.