Forwarded from Kotlin Multiplatform Broadcast
Что нового в релизе языка:
👉 Превью context parametr
👉 Non-local break и continue теперь stable
👉 Kotlin/JVM: изменения в генерации метода по умолчанию
👉 Kotlin/Native: улучшения в управлением памятью
👉 Kotlin/Wasm: wasmJs таргет отделили от js таргета
👉 Base64 стало Stable
#kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
❤40👍5🔥2
Media is too big
VIEW IN TELEGRAM
Прошла Kotlin Conf и в рамках keynote показали 3 фичи:
Версия на
#AndroidBroadcast #kotlin #kotlinconf25
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥28👍14❤5🤯1
Именно по этой причине Google не фокусируется на этих таргетах, хотя mingwX64 не обходит стороной.
#kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Forwarded from Kotlin Multiplatform Broadcast
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥1
Стек: #kotlin, #material3, #compose, Ktor, Room
#android #пример
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31🤯17❤4🔥2🎉1🤝1
where: Элегантное ограничение типов для чистоты и безопасностиКак часто в Android-разработке вы видели сомнительные
as-приведения? 🤔Вот пример, который недавно попался мне на глаза:
class Sample(private val activity: Activity) {
fun doSomething() {
// Опасно! Может упасть с ClassCastException,
// если activity не реализует LifecycleOwner
(activity as LifecycleOwner).lifecycle.addObserver(...)
}
}Опустим тот факт, что здесь стоит использовать слабую ссылку (
WeakReference) на Activity. Меня больше смутила необходимость вручную приводить Activity к LifecycleOwner.Да, в современной Android-разработке
AppCompatActivity и FragmentActivity реализуют этот интерфейс. Но наша цель — писать чистый и стабильный код, который не полагается на слепую веру, а гарантирует безопасность на уровне типов.💡Решение: Ограничение типов с помощью
whereВ Kotlin мы можем использовать условие
where для универсальных параметров, чтобы указать: «класс A должен быть одновременно и Activity, и LifecycleOwnerclass Sample<A>(private val activity: A)
where A : Activity,
A : LifecycleOwner {
fun doSomething() {
// Теперь activity можно использовать как LifecycleOwner
// БЕЗОПАСНО и без приведения типов
activity.lifecycle.addObserver(...)
}
}
Этот же подход отлично работает и для функций:
fun <A> doSomethingWith(activity: A)
where A : Activity,
A : LifecycleOwner {
// Полная типобезопасность
activity.lifecycle.addObserver(...)
}
В чем выигрыш?
Безопасность: Компилятор гарантирует, что в класс
Sample или функцию doSomethingWith можно передать только объект, который удовлетворяет обоим условиям:ClassCastException в рантайме.as.Используйте силу системы типов Kotlin на полную! Это делает код не только чище, но и стабильнее. 💪
#kotlin #android #androiddev
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍161🔥36❤22
🔥 Вышел JUnit 6 с поддержкой Kotlin
Прошло более 8 лет с релиза JUnit 5 (10 сентября 2017 года) и вот новая мажорная версия популярного фреймворка для написания Unit тестов в Java
Ключевые изменения в новой версии:
👉 Поддержка Java 17 и Kotlin 2.2+
👉 Переход на аннотации JSpecify
🏝 Поддержка корутин из Kotlin
👉 Поддержка Java Flight Recorder (JFR) из коробки
👉 Поддержка отмены выполнения теста
👉 Удалено deprecated API
👉
#тестирование #kotlin
Прошло более 8 лет с релиза JUnit 5 (10 сентября 2017 года) и вот новая мажорная версия популярного фреймворка для написания Unit тестов в Java
Ключевые изменения в новой версии:
👉 Поддержка Java 17 и Kotlin 2.2+
👉 Переход на аннотации JSpecify
👉 Поддержка Java Flight Recorder (JFR) из коробки
👉 Поддержка отмены выполнения теста
👉 Удалено deprecated API
👉
--fail-fast режим для запуска тестов из терминала#тестирование #kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥50👍10🤯3
Forwarded from Kotlin Multiplatform Broadcast
Please open Telegram to view this post
VIEW IN TELEGRAM
❤27🔥14👍12🤯5
Рабочая группа Swift on Android показала первую раннюю сборку Swift на Android. Я её изучил, посмотрел возможности и делюсь своими мыслями зачем они идут и смогут ли составить конкуренцию Kotlin Multiplatform
#AndroidBroadcast #kotlin #swift #apple #google #android
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🤔10❤2🔥2
Если вы уже уверенно пишете под Android, но хотите понять, как работает
Он включает теорию (видео и статьи) и практические задания 🧩
Из курса вы узнаете:
👉 Как устроена разработка с Kotlin Multiplatform
👉 Как превратить Android-проект в KMP с Android-таргетом
👉 Как использовать common- и platform-specific API
👉 Как интегрировать код в iOS-приложение
👉 Как мигрировать существующие решения на KMP
#kmp #kotlin #android #google #курс
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥78👍14🙏1
Saved State — это библиотека Jetpack, которая помогает сохранять и восстанавливать состояние при пересоздании, например из-за изменений конфигурации в Android или при выгрузке процесса системой. Поддерживает Kotlin Multiplatform
Вышел
androidx.savedstate:1.4.0, и в этом обновлении основное внимание уделено улучшению API. Ключевое изменение - добавлена нативная поддержка nullable типов в SavedStateRegistryOwner.saved, а также в функциях encodeToSavedState() и decodeFromSavedState() — теперь можно напрямую сохранять и восстанавливать null-значения без костылей.// Теперь это работает корректно без дополнительных проверок.
var name: String? by savedState(saved = "name", default = null)
#android #jetpack #kotlin #kmp #jetpackupdate #androidjetpack
Please open Telegram to view this post
VIEW IN TELEGRAM
👍19🔥8❤1
Для работы в Android надо подключить Gradle плагин
plugins {
id("dev.reformator.stacktracedecoroutinator") version "2.5.8"
}#android #kotlin #coroutines
Please open Telegram to view this post
VIEW IN TELEGRAM
👍38🔥6🤔3
Google выпустила долгожданный стабильный релиз DataStore 1.2.0. Эта версия приносит несколько важных улучшений, которые делают библиотеку ещё более мощной и удобной, особенно для проектов, не полностью перешедших на Kotlin Coroutines.
Ключевые нововведения:
✅ Поддержка Guava
Появился новый модуль
datastore-guava, который предоставляет API на основе ListenableFuture для разработчиков, использующих Guava. Теперь подключать DataStore в проекты на Java стало намного проще (а нужно было???)// Пример использования GuavaDataStore
val guavaDataStore: DataStore<Preferences> = GuavaDataStore.from(
produceFile = { context.preferencesDataStoreFile("settings.pb") },
serializer = PreferencesSerializer,
executor = Dispatchers.IO.asExecutor() // Используем Executor
)
ListenableFuture<Preferences> future = guavaDataStore.getData();
✅ Мультипроцессность для GuavaDataStore
Функциональность многопроцессного доступа, ранее доступная для Kotlin-версии, теперь добавлена и в
GuavaDataStore.✅ Поддержка Android Direct Boot - работа приложений до разблокировки устройства
DataStore теперь можно безопасно использовать в режиме Direct Boot. Для этого данные нужно разместить в защищённом хранилище устройства (Device Protected Storage).
val directBootDataStore = DataStoreFactory.createInDeviceProtectedStorage(
serializer = PreferencesSerializer
) { context.preferencesDataStoreFile("direct_boot_settings.pb") }
✅ Исправления важных багов
👉 Устранен
UnsatisifedLinkError при использовании R8 без стандартного ProGuard-файла.👉 Исправлена проблема, из-за которой операции
GuavaDataStore могли запускаться на главном потоке вместо указанного IO-диспетчера.👉 Решена проблема с
FileNotFoundException в OkioStorage при одновременном обращении к файлу (добавлена вторая попытка чтения).Прочие улучшения
👉 Добавлен
PreferencesFileSerializer — готовый сериализатор для работы с FileStorage.#Android #Jetpack #DataStore #Kotlin #Java #Guava
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍5
Google выпустила мажорное обновление библиотек Lifecycle. Этот релиз сфокусирован на улучшении интеграции с Compose.
rememberLifecycleOwner для ComposeНовый композабл позволяет создавать изолированные
LifecycleOwner внутри UI. Идеально для компонентов, которым нужно независимое управление состоянием — например, для HorizontalPager, где только активная страница должна быть в состоянии RESUMED.@Composable
fun MyComposable() {
val lifecycleOwner = rememberLifecycleOwner(
maxLifecycle = Lifecycle.State.RESUMED,
parentLifecycleOwner = LocalLifecycleOwner.current,
)
CompositionLocalProvider(
LocalLifecycleOwner provides lifecycleOwner
) {
// Дочерние композаблы теперь имеют собственный жизненный цикл
}
}
Новый артефакт
lifecycle-viewmodel-navigation3 предоставляет готовый декоратор для автоматической привязки ViewModel к отдельным экранам в Navigation 3.NavDisplay(
backStack = backStack,
entryDecorators = listOf(
rememberSaveableStateHolderNavEntryDecorator(),
rememberViewModelStoreNavEntryDecorator(), // Добавляем эту строку
),
entryProvider = entryProvider { /* ... */ }
)
Удобства для разработчиков:
👉 Идиоматичный Kotlin API для создания кастомных
CreationExtras CreationExtras {
this[MY_CUSTOM_KEY] = "myValue"
}
👉 Метод
savedStateHandle.saved() теперь нативно поддерживает nullable типы👉 Конструкторы SavedStateHandle помечены как
@VisibleForTesting⚠️ Важное изменение
Повышение
minSdk с API 21 до API 23 — убедитесь, что ваше приложение соответствует новым требованиям.#Jetpack #Lifecycle #Compose #Navigation #ViewModel #Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16🔥10🤯3👍2🙏1
Что дает библиотека
👉 Единый кроссплатформенный API для замены разрозненных решений
👉 Централизованная система управления всей навигацией в приложении
👉 Базовый слой для будущих навигационных решений Android
Пример использования:
val myHandler = object : NavigationEventHandler<NavigationEventInfo>(
initialInfo = CurrentInfo,
isBackEnabled = true
) {
override fun onBackStarted(event: NavigationEvent) {
// Подготовка к навигации
}
override fun onBackProgressed(event: NavigationEvent) {
// Анимации на основе event.progress
}
override fun onBackCompleted() {
// Завершение навигации
}
}
👉 Готовая интеграция с Compose
val navEventState = rememberNavigationEventState(
currentInfo = CurrentInfo,
backInfo = PreviousInfo
)
NavigationBackHandler(
state = navEventState,
isBackEnabled = true,
onBackCompleted = { /* Действие при завершении */ }
)
👉 Диспетчеры могут образовывать родительско-дочерние цепочки:
// Compose
val childDispatcher = rememberNavigationEventDispatcher(
parent =
LocalNavigationEventDispatcherOwner
.current
.navigationEventDispatcher
)
👉 Нативная поддержка Predictive Back из Android
👉 Библиотека уже используется в Activity 1.12.0 как базовый слой
#Jetpack #Navigation #Compose #KMP #PredictiveBack #Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16❤2
Если внимательно посмотреть на поведение людей в поисковых полях, становится понятно:
пальцы работают быстрее, чем приложение успевает реагировать.
Пользователь печатает «a», тут же «an», следом «and» — а приложение в панике пытается перестроить результаты после каждого шага. Поток начинает «стрелять» событиями, система перегружается, а интерфейс выглядит так, будто его кто-то перематывает на ускоренной перемотке.
Главная проблема здесь не скорость человека — а то, что приложение воспринимает каждую мелочь как повод что-то пересчитать.
Чтобы интерфейс работал предсказуемо, нужно научить поток реагировать не на каждое изменение, а на осмысленное завершение ввода.
⏳ Зачем нужен debounce()
Оператор debounce() работает как фильтр слишком быстрых изменений:
- быстрые изменения подряд — игнорируются
- устойчивое значение после паузы — двигаются по потоку дальше
Поток перестаёт реагировать на каждую букву и начинает слушать устойчивые состояния строки.
val results = queryFlow
.debounce(300) // значение задержки можно менять
.distinctUntilChanged()
.map { term -> searchData(term) }
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
------------
Помимо полезных символов, пользователь может случайно добавить пробел в конце или другой невидный символ. Фактически это тот же запрос — но без обработки поиск запустится повторно.
В таких случаях можно определиться как оператор distinctUntilChanged() будет сранивать значения:
queryFlow
.debounce(300)
.distinctUntilChanged { old, new ->
old.trim() == new.trim()
}
Теперь оба состояния считаются одинаковыми, и поиск не перезапускается зря.
#kotlin #coroutines #flow #android
Please open Telegram to view this post
VIEW IN TELEGRAM
8❤80👍54🤔3
Media is too big
VIEW IN TELEGRAM
FlowMVI - простая и эффективная библиотека для реализации MVI подхода в Android и Kotlin Multiplatform приложениях.
Из видео вы узнаете про возможности бибилотеки и интеграцию ее в проект.
Автор библиотеки Никита @nek_12 сделал серию видео с демонстрацией возможностей. Все видео будут доступны на YouTube и VK Video, а автору очень нужна ваша поддержка и обратная связь в комментариях под видео (а не этим постом).
#MVI #Архитектура #KMP #Kotlin #Кодинг
Please open Telegram to view this post
VIEW IN TELEGRAM
18🔥35🤔19❤6👍3🆒2🤯1
JetBrains объявила о важном изменении: с версии 2025.3 IntelliJ IDEA Community Edition и Ultimate объединяются в один продукт. Больше не нужно выбирать между двумя редакциями.
Всё основное — бесплатно: Базовый функционал для разработки на Java, Kotlin, поддержка Spring Boot, работа с базами данных и многое другое доступны сразу после установки без активации.
Важно:
JetBrains уже ранее закрыла Fleet. Кажется, что все шаги идут как оптимизация портфолио продуктов и упрощение разработки.
#JetBrains #IDEA #IDE #Java #Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
👍38❤12🔥10👎2
Forwarded from Kotlin Multiplatform Broadcast
Команда Kotlin выпустила финальную версию Kotlin 2.3.0. Обновление приносит новые стабильные возможности языка, улучшения производительности и поддержку новейших инструментов.
📢 Основные нововведения:
✅ Язык: Больше стабильных функций, проверка неиспользуемых возвращаемых значений, явные backing field.
✅ Kotlin/JVM: Поддержка Java 25.
✅ Kotlin/Native: Улучшенный Swift export, ускорение сборки, импорт C/Objective-C библиотек (бета).
✅ Kotlin/Wasm: Полные имена и новая модель исключений включены по умолчанию.
✅ Kotlin/JS: Экспериментальный export suspend-функций, новое представление LongArray.
✅ Gradle: Совместимость с Gradle 9.0, новый API для регистрации сгенерированных исходников.
✅ Compose compiler: Стектрейсы для минифицированных Android-приложений.
✅ Стандартная библиотека: Стабильные API для работы со временем и улучшенная работа с UUID.
📖 Подробнее на сайте
Каждую ключевую фичу подробно разберу в отдельном посте в канале @kotlin_broadcast. Следите за новостями!
#Kotlin
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥41👍3👎3❤2
Команда Compose представила opt-in API для улучшения читаемости стектрейсов во время разработки и для релизов.
Теперь становится возможным:
👉 Точно определять источник крешей в композиции, Side Effect (
LaunchedEffect, DisposableEffect) и корутинах из rememberCoroutineScope.👉 Изолировать падения для создания воспроизводимых примеров.
👉 Изучать креши, которые раньше показывали только внутренние фреймы Compose.
Достаточно добавить одну строку в точке входа в приложение (например, в
Application.onCreate()):// Включить stack trace только для минифицированных сборок (рекомендуемый способ)
Composer.setDiagnosticStackTraceMode(ComposeStackTraceMode.Auto)
// Или для локальной отладки (более точные, но тяжёлые трассировки)
Composer.setDiagnosticStackTraceMode(ComposeStackTraceMode.SourceInformation)
‼️ ВАЖНО Требуется Kotlin 2.3.0, а для режимов `Auto` и `GroupKeys` - включённый R8 с минификацией.
Есть несколько режимов работы
Auto (рекомендуется): использует GroupKeys для минифицированных сборок и None для отладочных.👉
GroupKeys: для минифицированных приложений. Использует маппинг-файл от R8 для восстановления примерного местоположения.👉
SourceInformation: для отладки. Даёт точные строки где произошел креш, но затратно по производительности. Стоит использовать только на этапе разработке.None: ничего не добавляет (поведение по умолчанию).Под капотом любой креш в Compose коде оборачивается в
DiagnosticComposeException, который добавляется в suppressed-исключения. В нём будет полная иерархия вызовов `@Composable` функций на момент падения!java.lang.IllegalStateException: Test layout error
at <original trace>
Suppressed: androidx.compose.runtime.DiagnosticComposeException:
Composition stack when thrown:
at ReusableComposeNode(Composables.kt:<unknown line>)
at Layout(Layout.kt:79)
at <lambda>(TempErrorsTest.kt:164) <-- Ваша функция!
... и т.д.
⚠️ Известные ограничения:
👉 В режиме
SourceInformation для первых фреймов могут не указываться номера строк (<unknown line>).👉
GroupKeys указывает только на первую строку @Composable функции.👉 Если сам сбор стектрейса упадёт, его исключение будет добавлено как suppressed.
Подробнее в официальной документации
#AndroidDev #Kotlin #Compose #R8 #Android
Please open Telegram to view this post
VIEW IN TELEGRAM
👍30❤6👎4🔥3