Пост 22. Orbit-MVI. Первое впечатление.
Попробовал https://github.com/orbit-mvi/orbit-mvi в качестве механизма управления состоянием для Compose (на самом деле можно использовать и вместе с фрагментами).
Впечатления пока приятные.
Ничего лишнего, по большому счету библиотека представляет собой контейнер с механизмом управления состоянием. Эдакий аналог того как бы вы управляли состоянием сами (через StateFlow, Flow), но все спрятано (почти все) под капотом. Код в целом становится почище.
Теперь ViewModel главного экрана выглядит так:
Как вам? Мне лично нравится такая простота. Да, у нас простенький пример, но все же!
Теперь немного пояснений.
1. Все состояние хранится в переменной container, которая обычно состоит из пары State, SideEffect. Обычно под Side Effect подразумевается показ тоаста, навигация на другой экран и вот такие вещи.
2. Как видите, стейт по-прежнему представляет из себя StateFlow<YourState>. То бишь, работа со стейтом просто немного спрятана и не нужно писать кучу переменных во ViewModel.
3. Как и раньше, ViewModel у нас представляет из себя Store (в терминах Redux, сущность, которая хранит состояние), но теперь мы наследуемся от библиотечного интерфейса ContainerHost<MainState, MainSideEffect> передавая в него состояние нашего экрана и сайд эффект. Интерфейс как раз и вынуждает нас переопределять переменную container.
4. Функция container<State, SideEffect>() принимает также блок, который выполнится при первом обращении к переменной. В нашем случае, удобно поместить в этот блок первую загрузку погодных данных.
5. Намерение (в терминах Redux) - это некое действие, обычно пользовательское. Обычно каждое намерение меняет стейт (копируя его, а не переопределяя) через вызов функции redux. Собственно, у нас все также. В блоке intent мы можем сделать какие-либо действия для получения данных, в скоупе корутин, а в самой функции redux мы лишь копируем нужные нам данные в новый стейт через функцию copy, которая доступна для data-классов. Тем самым у нас immutable-стейт, что как раз по канонам Unidirectional Data Flow.
Со стороны Compose все взаимодействие с состоянием выглядит так:
Со стороны Compose особо ничего не поменялось. В переменной container как раз и хранится состояние, а эффекты в container.sideEffectFlow.
Так или иначе, подобные архитектуры скоро станут мейнстримом в мобайле!
А вы что думаете про это все?
Попробовал https://github.com/orbit-mvi/orbit-mvi в качестве механизма управления состоянием для Compose (на самом деле можно использовать и вместе с фрагментами).
Впечатления пока приятные.
Ничего лишнего, по большому счету библиотека представляет собой контейнер с механизмом управления состоянием. Эдакий аналог того как бы вы управляли состоянием сами (через StateFlow, Flow), но все спрятано (почти все) под капотом. Код в целом становится почище.
Теперь ViewModel главного экрана выглядит так:
@HiltViewModel
class MainViewModel @Inject constructor(
private val interactor: WeatherInteractor
) : ViewModel(), ContainerHost<MainState, MainSideEffect> {
override val container = container<MainState, MainSideEffect>(MainState()) {
loadWeather()
}
private fun loadWeather(fromRefresh: Boolean = false) = intent {
val mainWeather = interactor.getMainWeatherData(fromRefresh)
val daysWeather = interactor.getDaysWeatherData(fromRefresh)
val hoursWeather = interactor.getHoursWeatherData(fromRefresh)
reduce {
state.copy(
mainWeather = mainWeather,
daysWeather = daysWeather,
hoursWeather = hoursWeather,
isRefreshing = false
)
}
}
fun pullToRefresh() = intent {
reduce {
state.copy(isRefreshing = true)
}
delay(3000) //TODO just for sample
loadWeather(fromRefresh = true)
}
}
Как вам? Мне лично нравится такая простота. Да, у нас простенький пример, но все же!
Теперь немного пояснений.
1. Все состояние хранится в переменной container, которая обычно состоит из пары State, SideEffect. Обычно под Side Effect подразумевается показ тоаста, навигация на другой экран и вот такие вещи.
2. Как видите, стейт по-прежнему представляет из себя StateFlow<YourState>. То бишь, работа со стейтом просто немного спрятана и не нужно писать кучу переменных во ViewModel.
3. Как и раньше, ViewModel у нас представляет из себя Store (в терминах Redux, сущность, которая хранит состояние), но теперь мы наследуемся от библиотечного интерфейса ContainerHost<MainState, MainSideEffect> передавая в него состояние нашего экрана и сайд эффект. Интерфейс как раз и вынуждает нас переопределять переменную container.
4. Функция container<State, SideEffect>() принимает также блок, который выполнится при первом обращении к переменной. В нашем случае, удобно поместить в этот блок первую загрузку погодных данных.
5. Намерение (в терминах Redux) - это некое действие, обычно пользовательское. Обычно каждое намерение меняет стейт (копируя его, а не переопределяя) через вызов функции redux. Собственно, у нас все также. В блоке intent мы можем сделать какие-либо действия для получения данных, в скоупе корутин, а в самой функции redux мы лишь копируем нужные нам данные в новый стейт через функцию copy, которая доступна для data-классов. Тем самым у нас immutable-стейт, что как раз по канонам Unidirectional Data Flow.
Со стороны Compose все взаимодействие с состоянием выглядит так:
@Composable
fun MainScreen() {
val viewModel: MainViewModel = hiltViewModel()
val state = viewModel.container.stateFlow.collectAsState().value
ShowWeather(
viewModel,
state.mainWeather,
state.daysWeather,
state.hoursWeather
)
}
Со стороны Compose особо ничего не поменялось. В переменной container как раз и хранится состояние, а эффекты в container.sideEffectFlow.
Так или иначе, подобные архитектуры скоро станут мейнстримом в мобайле!
А вы что думаете про это все?
GitHub
GitHub - orbit-mvi/orbit-mvi: A simple MVI framework for Kotlin Multiplatform and Android
A simple MVI framework for Kotlin Multiplatform and Android - orbit-mvi/orbit-mvi
Друзья, тут такое дело.
В свободное время ковыряю потихоньку iOS и еще медленнее Flutter. Но все же!
Было бы вам интересно почитать что-нибудь про них и, например, про KMM?
В свободное время ковыряю потихоньку iOS и еще медленнее Flutter. Но все же!
Было бы вам интересно почитать что-нибудь про них и, например, про KMM?
Final Results
74%
Да
26%
Нет, интересен только Android
Что новенького в рассылках #6
Забавная либа: https://github.com/kojofosu/SplitButton
Функционал чем-то напоминает улучшенную версию Spinner-ов. Для сложных экранов может пригодиться.
Либа для роутинга: https://github.com/Zhuinden/simple-stack/
Выглядит не так плохо, как большинство, но вцелом можно подождать и свежую библиотеку от автора Cicherone, или юзать Navigation Library из JetPack.
Вышел Realm Kotlin 0.6.0: https://medium.com/realm/realm-kotlin-0-6-0-baa26dcbbb9
Либа для конвертации разных форматов в виде DSL-ки с разными операторами: https://github.com/nomemory/mapneat
Интересная часть - конвертация POJO в JSON. Может пригодится, правда под капотом дофига всего тянет.
Демка по KMM: https://github.com/joreilly/FantasyPremierLeague
Как-нибудь ее разберем с вами.
В качества UI: Compose и SwiftUI.
Кстати, кто не в курсе. SwiftUI во многом аналогичный Compose UI-тулкит для iOS, но появился (если не путаю) аж в 2018-ом! Так что, разобравшись с Compose будет проще понимать в будущем и SwiftUI. А вот preview функций SwiftUI в XCode работает пока гораздо стабильнее, чем аналогичная история для Compose в Android Studio.
Либа для создания разных фабрик: https://github.com/bluegroundltd/kfactory
Во многом нужна для более удобного тестирования. Помогает подготовить фабрики данных для моделей, которые потом можно использовать в Unit-тестах.
Напоследок.
Roadmap по изучению Compose:
https://victorbrandalise.com/roadmap-for-jetpack-compose/
Забавная либа: https://github.com/kojofosu/SplitButton
Функционал чем-то напоминает улучшенную версию Spinner-ов. Для сложных экранов может пригодиться.
Либа для роутинга: https://github.com/Zhuinden/simple-stack/
Выглядит не так плохо, как большинство, но вцелом можно подождать и свежую библиотеку от автора Cicherone, или юзать Navigation Library из JetPack.
Вышел Realm Kotlin 0.6.0: https://medium.com/realm/realm-kotlin-0-6-0-baa26dcbbb9
Либа для конвертации разных форматов в виде DSL-ки с разными операторами: https://github.com/nomemory/mapneat
Интересная часть - конвертация POJO в JSON. Может пригодится, правда под капотом дофига всего тянет.
Демка по KMM: https://github.com/joreilly/FantasyPremierLeague
Как-нибудь ее разберем с вами.
В качества UI: Compose и SwiftUI.
Кстати, кто не в курсе. SwiftUI во многом аналогичный Compose UI-тулкит для iOS, но появился (если не путаю) аж в 2018-ом! Так что, разобравшись с Compose будет проще понимать в будущем и SwiftUI. А вот preview функций SwiftUI в XCode работает пока гораздо стабильнее, чем аналогичная история для Compose в Android Studio.
Либа для создания разных фабрик: https://github.com/bluegroundltd/kfactory
Во многом нужна для более удобного тестирования. Помогает подготовить фабрики данных для моделей, которые потом можно использовать в Unit-тестах.
Напоследок.
Roadmap по изучению Compose:
https://victorbrandalise.com/roadmap-for-jetpack-compose/
GitHub
GitHub - kojofosu/SplitButton: A dual-function menu button that offers a default action as well as the possibility of choosing…
A dual-function menu button that offers a default action as well as the possibility of choosing a different action by selecting from a set of alternatives. - GitHub - kojofosu/SplitButton: A dual-...
Если готовитесь к собесу - 50 вопросов с ответами:
https://code.coursesity.com/android-interview-questions
Вопросы скорее для подготовки на позицию джуна или начинающего миддла максимум.
https://code.coursesity.com/android-interview-questions
Вопросы скорее для подготовки на позицию джуна или начинающего миддла максимум.
Coursesity
Top 50 Android Interview Questions For Android Developer Jobs
If you are preparing for an Android developer interview, this article contains the top 50 Android Interview Questions & Answers to help you out.
Тут сравнили скорость компиляции Android-проектов на:
1. 2021 14" MacBook Pro — M1 Pro (10 core)— 32gb RAM
2. Desktop (Pop_OS!) — 4.2ghz AMD 2950x (16 core) — 64gb RAM
3. 2019 16" MacBook Pro — 2.4ghz Intel i9 (8 core)–32gb RAM
И M1 Pro показал себя очень и очень неплохо, проиграв ДЕСКТОПУ лишь на Clean Build!
Впечатляет!
1. 2021 14" MacBook Pro — M1 Pro (10 core)— 32gb RAM
2. Desktop (Pop_OS!) — 4.2ghz AMD 2950x (16 core) — 64gb RAM
3. 2019 16" MacBook Pro — 2.4ghz Intel i9 (8 core)–32gb RAM
И M1 Pro показал себя очень и очень неплохо, проиграв ДЕСКТОПУ лишь на Clean Build!
Впечатляет!
Medium
The M1 Pro for Android Engineers
How well do the new M1 Pro MacBooks stack up for Android Development?
Поигрался немного с созданием, запуском проектов на Flutter и KMM.
1. Для обеих платформ предлагается плагин под Android Studio. И нужно сказать, под Flutter он пока выглядит интереснее. Например, есть возможность открыть каждый специфичный модуль либо в Xcode, либо в отдельном экземпляре Android Studio (AS). А вот у плагина для KMM такого нет.
2. Flutter-проект запустился на обеих платформах, и даже в Chrome, что несомненно круто! (но стоит сказать, что когда AS не видит симулятор iOS, приходится запускать проект из Xcode, благо это делается быстро через контекстное меню в AS).
3. KMM-проект так и не запустился на iOS. И, к слову, почему-то при настройке проекта в мастере, не выбирается нужный тул из доки (Xcode Build phases). Вообщем, тут нужно явно посидеть и понастраивать.
4. Flutter-овский Hot Reload - это не что! Как будто вы кодите веб-приложение. Что-то поменял в коде (например, текст заголовка) и тут же изменения видны в эмуляторе/симуляторе, без всяких Clean-Build и повторных запусков. Кайф!
5. Помните open source проект на KMM - https://github.com/joreilly/FantasyPremierLeague ? Думаю, попробую импортнуть в AS и запустить. Вдруг запустится нормально на iOS. Но… проект будто не узнает эту структуру и считает его обычным проектом под Android. И на Android-эмуляторе запустился (правда крашнулся после нажатия на Поиск, но не суть). А вот то, что его можно запустить под iOS, видимо, знает только автор этого проекта. AS не видит даже подобной настройки. Возможно, он был создан по другой структуре и новый плагин для KMM ее не понимает. Вообщем, тоже не вышло - нужны пляски с бубном и здесь.
6. Но дока, кстати, для обеих платформ (по крайней мере, чтобы быстро стартануть) более-менее. Под KMM чуть хуже, но есть отдельные гайды по запуску проекта под iOS и там, так что попробуем победить эту проблему.
Вообщем, Flutter, пока выглядит интереснее. Но немного отталкивает сам язык Dart - какие никакие отличия в нем между Java / Kotlin есть, хотя с виду он не очень сложный.
У KMM общие части можно писать на Kotlin, что для нас плюс, а какие-то платформенно-специфичные уже открывать в Xcode и кодить на Swift.
1. Для обеих платформ предлагается плагин под Android Studio. И нужно сказать, под Flutter он пока выглядит интереснее. Например, есть возможность открыть каждый специфичный модуль либо в Xcode, либо в отдельном экземпляре Android Studio (AS). А вот у плагина для KMM такого нет.
2. Flutter-проект запустился на обеих платформах, и даже в Chrome, что несомненно круто! (но стоит сказать, что когда AS не видит симулятор iOS, приходится запускать проект из Xcode, благо это делается быстро через контекстное меню в AS).
3. KMM-проект так и не запустился на iOS. И, к слову, почему-то при настройке проекта в мастере, не выбирается нужный тул из доки (Xcode Build phases). Вообщем, тут нужно явно посидеть и понастраивать.
4. Flutter-овский Hot Reload - это не что! Как будто вы кодите веб-приложение. Что-то поменял в коде (например, текст заголовка) и тут же изменения видны в эмуляторе/симуляторе, без всяких Clean-Build и повторных запусков. Кайф!
5. Помните open source проект на KMM - https://github.com/joreilly/FantasyPremierLeague ? Думаю, попробую импортнуть в AS и запустить. Вдруг запустится нормально на iOS. Но… проект будто не узнает эту структуру и считает его обычным проектом под Android. И на Android-эмуляторе запустился (правда крашнулся после нажатия на Поиск, но не суть). А вот то, что его можно запустить под iOS, видимо, знает только автор этого проекта. AS не видит даже подобной настройки. Возможно, он был создан по другой структуре и новый плагин для KMM ее не понимает. Вообщем, тоже не вышло - нужны пляски с бубном и здесь.
6. Но дока, кстати, для обеих платформ (по крайней мере, чтобы быстро стартануть) более-менее. Под KMM чуть хуже, но есть отдельные гайды по запуску проекта под iOS и там, так что попробуем победить эту проблему.
Вообщем, Flutter, пока выглядит интереснее. Но немного отталкивает сам язык Dart - какие никакие отличия в нем между Java / Kotlin есть, хотя с виду он не очень сложный.
У KMM общие части можно писать на Kotlin, что для нас плюс, а какие-то платформенно-специфичные уже открывать в Xcode и кодить на Swift.
Нельзя жить с разбитыми окнами!
Во время чтения книги "Программист-прагматик" запомнился довольно интересный принцип, который действительно встречается в долгоиграющих проектах.
Далее, интересные фрагменты из книги.
—
Имеется немало факторов, способствующих деградации программного обеспечения, и самый важный из них, по-видимому, имеет отношение к психологии или культуре в работе над проектом. Какими бы совершенными ни были составленные планы или участники проекта, он все равно может быть подвергнут деградации и разрушению в течении всего срока своего действия. Тем не менее существуют и такие проекты, которые успешно противостоят естественной тенденции к беспорядку и ухитряются завершиться вполне удачно, несмотря на огромные трудности и постоянные задержки и помехи.
В чем же тогда отличия? В старых кварталах городов одни здания красивы и чисты, тогда как другие выглядят как трухлявые развалины. Исследователи в сфере преступности и упадка городов открыли замечательный пусковой механизм, очень быстро превращающий чистое, нетронутое, нежилое здание в разрушенную и заброшенную трущобу. Это разбитое окно.
Оказывается, что если не отремонтировать хотя бы одно разбитое окно в течении какого-нибудь значительного периода времени, у жильцов возникнет ощущение заброшенности здания, а следовательно, отсутствия заботы городских властей о его состоянии. И, как следствие, разбивается еще одно окно, а люди начинают захламлять здание всяким мусором. В течении относительно короткого периода времени здание разрушается настолько, что у его владельца не возникает никакого желания отремонтировать его, и тогда ощущение заброшенности становится вполне реальным.
Как показывают исследования, безнадежность оказывается заразной.
Совет: "Нельзя жить с разбитыми окнами"
По существу, означает, что нельзя мириться с неудачными проектными решениями или плохо написанными фрагментами кода, оставляя их неисправленными. Исправляйте их, как только обнаружите. Если же времени на исправление недостаточно, закомментируйте неисправный код, выведите сообщение "Не реализовано" или же подставьте вместо него фиктивные данные подобно тому, как временно заколачивают разбитые окна. Словом, предпримите какое-то действие, чтобы предотвратить дальнейший ущерб и тем самым показать, что владеете ситуацией.
Еще один совет из этой же серии: прежде всего не навредить!
Присоединившись к проекту, где код безупречен, вам следует действовать крайне осторожно, чтобы не навредить.
—
А вы встречали подобное в своей практике?
Во время чтения книги "Программист-прагматик" запомнился довольно интересный принцип, который действительно встречается в долгоиграющих проектах.
Далее, интересные фрагменты из книги.
—
Имеется немало факторов, способствующих деградации программного обеспечения, и самый важный из них, по-видимому, имеет отношение к психологии или культуре в работе над проектом. Какими бы совершенными ни были составленные планы или участники проекта, он все равно может быть подвергнут деградации и разрушению в течении всего срока своего действия. Тем не менее существуют и такие проекты, которые успешно противостоят естественной тенденции к беспорядку и ухитряются завершиться вполне удачно, несмотря на огромные трудности и постоянные задержки и помехи.
В чем же тогда отличия? В старых кварталах городов одни здания красивы и чисты, тогда как другие выглядят как трухлявые развалины. Исследователи в сфере преступности и упадка городов открыли замечательный пусковой механизм, очень быстро превращающий чистое, нетронутое, нежилое здание в разрушенную и заброшенную трущобу. Это разбитое окно.
Оказывается, что если не отремонтировать хотя бы одно разбитое окно в течении какого-нибудь значительного периода времени, у жильцов возникнет ощущение заброшенности здания, а следовательно, отсутствия заботы городских властей о его состоянии. И, как следствие, разбивается еще одно окно, а люди начинают захламлять здание всяким мусором. В течении относительно короткого периода времени здание разрушается настолько, что у его владельца не возникает никакого желания отремонтировать его, и тогда ощущение заброшенности становится вполне реальным.
Как показывают исследования, безнадежность оказывается заразной.
Совет: "Нельзя жить с разбитыми окнами"
По существу, означает, что нельзя мириться с неудачными проектными решениями или плохо написанными фрагментами кода, оставляя их неисправленными. Исправляйте их, как только обнаружите. Если же времени на исправление недостаточно, закомментируйте неисправный код, выведите сообщение "Не реализовано" или же подставьте вместо него фиктивные данные подобно тому, как временно заколачивают разбитые окна. Словом, предпримите какое-то действие, чтобы предотвратить дальнейший ущерб и тем самым показать, что владеете ситуацией.
Еще один совет из этой же серии: прежде всего не навредить!
Присоединившись к проекту, где код безупречен, вам следует действовать крайне осторожно, чтобы не навредить.
—
А вы встречали подобное в своей практике?
👍1
Красота!
Скоро дизайн под Android будут делать дизайнеры в прямом смысле этого слова🙂
https://www.figma.com/community/plugin/856651176156241740/Figma-to-Compose
Осталось им добавить в работу "чуточку" системности.
Скоро дизайн под Android будут делать дизайнеры в прямом смысле этого слова🙂
https://www.figma.com/community/plugin/856651176156241740/Figma-to-Compose
Осталось им добавить в работу "чуточку" системности.
Figma
Figma to Compose | Figma Community
Figma Community plugin - (beta, code won't exactly match input)
Easily convert Figma designs directly to Kotlin code for Jetpack Compose. (Not affiliated with either of them)
Often times designs contain non-repeated distances, colours and proportions. Replicating…
Easily convert Figma designs directly to Kotlin code for Jetpack Compose. (Not affiliated with either of them)
Often times designs contain non-repeated distances, colours and proportions. Replicating…
Telegram теперь встраивает собственные рекламные посты в каналах. Они все отмечены знаком «Спонсировано». Поэтому, если увидите такой пост (мало ли!) — знайте, влиять на спонсорский контент от Telegram авторы каналов пока никак не могут, а, следовательно, не могут отвечать за достоверность информации и ее качество.
Будьте аккуратны!
Будьте аккуратны!
Старый Мобильщик pinned «Telegram теперь встраивает собственные рекламные посты в каналах. Они все отмечены знаком «Спонсировано». Поэтому, если увидите такой пост (мало ли!) — знайте, влиять на спонсорский контент от Telegram авторы каналов пока никак не могут, а, следовательно,…»
Небольшой пример Bottom Sheet на Compose
В сети можно встретить, например, такой вариант реализации Bottom Sheets:
https://proandroiddev.com/how-to-master-swipeable-and-nestedscroll-modifiers-in-compose-bb0635d6a760
Но, по-моему, он полезен скорее, как пример работы с разными модификаторами, а также показывает, что можно довольно просто создавать свои компоненты.
А вот для Bottom Sheets есть готовое решение, основанное на BottomSheetScaffold:
И да, список внутри Bottom Sheet прекрасно работает. Хотя тут он довольно простой.
Теперь нам нужна кнопка, которая будет менять состояние нашего Bottom Sheet (параметр bottomSheetScaffoldState) и в зависимости от него он и будет показываться / скрываться.
Все довольно просто.
Но самое интересное, что для Bottom Sheet можно даже указать Top Bar, Floating Action Button и кучу других вещей (например, цвет контента, цвет шита и т.д.). Все потому что его реализовали как обычный Scaffold, который также имеет заготовку так называемых слотов: https://developer.android.com/jetpack/compose/layouts/basics#slot-based-layouts.
Почему они так сделали с Bottom Sheet не очень понятно, но возможность такая есть.
В сети можно встретить, например, такой вариант реализации Bottom Sheets:
https://proandroiddev.com/how-to-master-swipeable-and-nestedscroll-modifiers-in-compose-bb0635d6a760
Но, по-моему, он полезен скорее, как пример работы с разными модификаторами, а также показывает, что можно довольно просто создавать свои компоненты.
А вот для Bottom Sheets есть готовое решение, основанное на BottomSheetScaffold:
@ExperimentalMaterialApi
@Composable
fun BottomSheet(bottomSheetScaffoldState: BottomSheetScaffoldState) {
BottomSheetScaffold(
scaffoldState = bottomSheetScaffoldState,
sheetContent = {
LazyColumn {
items(6) {
Text("$it")
}
}
},
sheetPeekHeight = 0.dp,
sheetBackgroundColor = Color.Gray
){}
}
И да, список внутри Bottom Sheet прекрасно работает. Хотя тут он довольно простой.
Теперь нам нужна кнопка, которая будет менять состояние нашего Bottom Sheet (параметр bottomSheetScaffoldState) и в зависимости от него он и будет показываться / скрываться.
val bottomSheetScaffoldState = rememberBottomSheetScaffoldState(
bottomSheetState = BottomSheetState(BottomSheetValue.Collapsed)
)
...
Button(onClick = {
coroutineScope.launch {
if (bottomSheetScaffoldState.bottomSheetState.isCollapsed) {
bottomSheetScaffoldState.bottomSheetState.expand()
} else {
bottomSheetScaffoldState.bottomSheetState.collapse()
}
}
}) {
Text(text = "Show/Hide BottomSheet")
}
Все довольно просто.
Но самое интересное, что для Bottom Sheet можно даже указать Top Bar, Floating Action Button и кучу других вещей (например, цвет контента, цвет шита и т.д.). Все потому что его реализовали как обычный Scaffold, который также имеет заготовку так называемых слотов: https://developer.android.com/jetpack/compose/layouts/basics#slot-based-layouts.
Почему они так сделали с Bottom Sheet не очень понятно, но возможность такая есть.
Тут оказывается в августе вышло потенциально интересное чтиво от команды Android:
https://chethaase.medium.com/androids-765c803d5ff6
Chet Haase в своей книге, которую он писал 4 года, расскажет почему Android стал таким успешным, как это было, как шла разработка и о команде, которая нам подарила сие чудо.
Кстати, хороший вариант на подарок.
Правда на русском пока не встречал или таки уже есть?
https://chethaase.medium.com/androids-765c803d5ff6
Chet Haase в своей книге, которую он писал 4 года, расскажет почему Android стал таким успешным, как это было, как шла разработка и о команде, которая нам подарила сие чудо.
Кстати, хороший вариант на подарок.
Правда на русском пока не встречал или таки уже есть?
Medium
Androids
A Book is Born
Полезный пост про Inline Classes в Kotlin.
Inline (value) classes появились еще в Kotlin 1.3 и наконец-то вышли в релизной версии вместе с Kotlin 1.5.0. В некоторых моментах напоминают структуры (struct) в других языках программирования.
Ждали эту фичу или не особо?
Inline (value) classes появились еще в Kotlin 1.3 и наконец-то вышли в релизной версии вместе с Kotlin 1.5.0. В некоторых моментах напоминают структуры (struct) в других языках программирования.
Ждали эту фичу или не особо?
Medium
Kotlin Inline Classes in an Android World
The Kotlin Inline (Value) class is a relatively new feature of the Kotlin language as it recently got a stable release in Kotlin 1.5. I…
Судя по отзывам коллег, https://proxyman.io - отличная альтернатива Charles Proxy.
По крайней мере, настроить моки получается проще и удобнее.
Надо бы попробовать.
А вы что используете для моков API?
Накидывайте альтернативы Charles Proxy, если юзаете что-то подобное.
По крайней мере, настроить моки получается проще и удобнее.
Надо бы попробовать.
А вы что используете для моков API?
Накидывайте альтернативы Charles Proxy, если юзаете что-то подобное.
Proxyman
Proxyman · Debug, intercept & mock HTTP with Proxyman
Proxyman is a native, high-performance macOS app, which enables developers to capture, inspect, and manipulate HTTP/HTTPS requests/responses with ease. Support iOS and Android Simulator and Physical Device.
МТС Банк поделился впечатлениями о Compose в продакшене:
https://habr.com/ru/company/ru_mts/blog/588096/
https://habr.com/ru/company/ru_mts/blog/588096/
Хабр
Использование Jetpack Compose в продакшне: первые впечатления
Мы в МТС Банке давно ждали релиза Jetpack Compose, чтобы использовать его в продакшне. В прошлом месяце такая возможность наконец появилась — мы решили обновить дизайн одного из экранов нашего...
Некоторые мысли после нескольких часов создания и запуска проекта на KMM.
Спросите: почему так много часов?
На самом деле, хотелось, чтобы проект билдился и запускался и на iOS прямиком из Android Studio. C запуском на Android как раз проблем не было.
По итогу:
1. Текущая версия KMM-плагина 0.3 работает с Kotlin 1.6 и Gradle plugin 7.0.0+. Но штука вот в чем. Если у вас не последние версии Kotlin, Java SE ниже 11-версии и студия не самая свежая (вероятно дело больше в версии Gradle Plugin), то создавая KMM-проект в AS он вылетет с ошибкой и не до конца создаст структуру проекта. И потом плагин просто disabled-тся. Обновили окружение и потом вручную включили плагин снова.
2. Для успешного запуска проекта на iOS-симуляторе нужен Xcode 12.5+ на текущей версии плагина KMM. Вероятно и версия 12.0+ сгодится, но не проверял. Но боль лично для меня в том, что Xcode 12+ доступен только на BigSur, которую я пока не ставил на рабочий iMac. Благо обновил Mac Pro и удалось немного поэкспериментировать.
3. Кстати, про Xcode. Вероятно, его можно попробовать заменить на AppCode или какими-то плагинами для Swift под AS, чтобы можно было кодить в одной среде и на Kotlin и на Swift, но скорее всего, когда проект дойдет до полноценной разработки, Xcode понадобится.
4. Дока по KMM на kotlinlang.org оставляет желать лучшего. Странное структурирование с бесконечными перекрестными ссылками, быстро устаревает, но что-то интересное почерпнуть можно и нужно. Плюс ее маловато. Хотелось бы больше инфы и кейсов.
5. В AS (есть отдельный конфиг для запуска iOS app) даже можно настроить, например, на каком симуляторе запускать проект, что однозначно радует.
6. Самое забавное - это запуск проекта на iOS. Как же забавно видеть старт iOS-симулятора прямиком из AS. И оно работает! После некоторых телодвижений :)
7. В целом, прикольные ощущения. Есть общий модуль shared с общей кодовой базой (обычно бизнес-логика), есть конкретные реализации UI на Android/iOS, которые как раз используют эту самую бизнес-логику. А если вспомнить, что Kotlin можно попробовать развернуть и на Web (Kotlin JS), то эту логику в теории можно будет использовать и там. Круто? Очень! Но без нюансов, конечно, не обойдется.
Про структуру проекта поговорим подробнее чуть позже.
Итак, рабочая конфигурация для плагина KMM 0.3:
- Java SE 11 (можно попробовать и OpenJDK)
- AS Arctic Fox 2020.3.1 Patch 3
- Xcode 12.5.1
- Kotlin 1.6.0
- Gradle Plugin 7.0.3
Спросите: почему так много часов?
На самом деле, хотелось, чтобы проект билдился и запускался и на iOS прямиком из Android Studio. C запуском на Android как раз проблем не было.
По итогу:
1. Текущая версия KMM-плагина 0.3 работает с Kotlin 1.6 и Gradle plugin 7.0.0+. Но штука вот в чем. Если у вас не последние версии Kotlin, Java SE ниже 11-версии и студия не самая свежая (вероятно дело больше в версии Gradle Plugin), то создавая KMM-проект в AS он вылетет с ошибкой и не до конца создаст структуру проекта. И потом плагин просто disabled-тся. Обновили окружение и потом вручную включили плагин снова.
2. Для успешного запуска проекта на iOS-симуляторе нужен Xcode 12.5+ на текущей версии плагина KMM. Вероятно и версия 12.0+ сгодится, но не проверял. Но боль лично для меня в том, что Xcode 12+ доступен только на BigSur, которую я пока не ставил на рабочий iMac. Благо обновил Mac Pro и удалось немного поэкспериментировать.
3. Кстати, про Xcode. Вероятно, его можно попробовать заменить на AppCode или какими-то плагинами для Swift под AS, чтобы можно было кодить в одной среде и на Kotlin и на Swift, но скорее всего, когда проект дойдет до полноценной разработки, Xcode понадобится.
4. Дока по KMM на kotlinlang.org оставляет желать лучшего. Странное структурирование с бесконечными перекрестными ссылками, быстро устаревает, но что-то интересное почерпнуть можно и нужно. Плюс ее маловато. Хотелось бы больше инфы и кейсов.
5. В AS (есть отдельный конфиг для запуска iOS app) даже можно настроить, например, на каком симуляторе запускать проект, что однозначно радует.
6. Самое забавное - это запуск проекта на iOS. Как же забавно видеть старт iOS-симулятора прямиком из AS. И оно работает! После некоторых телодвижений :)
7. В целом, прикольные ощущения. Есть общий модуль shared с общей кодовой базой (обычно бизнес-логика), есть конкретные реализации UI на Android/iOS, которые как раз используют эту самую бизнес-логику. А если вспомнить, что Kotlin можно попробовать развернуть и на Web (Kotlin JS), то эту логику в теории можно будет использовать и там. Круто? Очень! Но без нюансов, конечно, не обойдется.
Про структуру проекта поговорим подробнее чуть позже.
Итак, рабочая конфигурация для плагина KMM 0.3:
- Java SE 11 (можно попробовать и OpenJDK)
- AS Arctic Fox 2020.3.1 Patch 3
- Xcode 12.5.1
- Kotlin 1.6.0
- Gradle Plugin 7.0.3
И сразу небольшой анонс на ближайшие (и не очень) планы.
KMM понравился, поэтому будем пошагово ковырять. Есть ощущение, что за этим будущее, но поглядим.
Создал репу: https://github.com/Djangist/ToDoApp в которой будем делать кроссплатформенный Todo App на KMM. Уже можно стянуть пустую болванку, настроить окружение, попробовать собрать и запустить.
Что хотелось бы сделать в этом аппе?
1. Общую бизнес-логику заметок для обеих платформ.
2. Общий Rest API c репозиториями, интеракторами и вот этим всем. Например, прикрутить что-то вроде: https://developers.google.com/tasks/reference/rest для синхронизации задач из Google-акка. Но надо подумать.
3. Compose / SwiftUI, а может к этому времени сделают поддержку Compose и на iOS? Есть уже Compose Multiplatform.
4. MVI-архитектура для presеntation-слоя.
5. Базовый функционал: CRUD-интерфейс, sharing заметок, оффлайн-режим.
6. Кроссплатформенный DI? Уфф...
7. Предлагайте свои идеи!
Flutter тоже будем ковырять. Он не менее интересен, чем KMM. По крайней мере, для ниши «создать быстрый кроссплатформенный прототип» под все платформы - самое то!
Как раз, есть мысль переписать свой старенький апп, но пока еще не решил на какую платформу.
Будем дальше разбираться с Compose и MVI.
Доделаю собственный велосипед для MVI. Пока там есть проблемы, но не хватает времени.
И само собой, будем и дальше вникать в тонкости самого Android, Kotlin, и немножко изучать Swift / iOS.
KMM понравился, поэтому будем пошагово ковырять. Есть ощущение, что за этим будущее, но поглядим.
Создал репу: https://github.com/Djangist/ToDoApp в которой будем делать кроссплатформенный Todo App на KMM. Уже можно стянуть пустую болванку, настроить окружение, попробовать собрать и запустить.
Что хотелось бы сделать в этом аппе?
1. Общую бизнес-логику заметок для обеих платформ.
2. Общий Rest API c репозиториями, интеракторами и вот этим всем. Например, прикрутить что-то вроде: https://developers.google.com/tasks/reference/rest для синхронизации задач из Google-акка. Но надо подумать.
3. Compose / SwiftUI, а может к этому времени сделают поддержку Compose и на iOS? Есть уже Compose Multiplatform.
4. MVI-архитектура для presеntation-слоя.
5. Базовый функционал: CRUD-интерфейс, sharing заметок, оффлайн-режим.
6. Кроссплатформенный DI? Уфф...
7. Предлагайте свои идеи!
Flutter тоже будем ковырять. Он не менее интересен, чем KMM. По крайней мере, для ниши «создать быстрый кроссплатформенный прототип» под все платформы - самое то!
Как раз, есть мысль переписать свой старенький апп, но пока еще не решил на какую платформу.
Будем дальше разбираться с Compose и MVI.
Доделаю собственный велосипед для MVI. Пока там есть проблемы, но не хватает времени.
И само собой, будем и дальше вникать в тонкости самого Android, Kotlin, и немножко изучать Swift / iOS.
GitHub
GitHub - Djangist/ToDoApp
Contribute to Djangist/ToDoApp development by creating an account on GitHub.
Старый Мобильщик pinned «И сразу небольшой анонс на ближайшие (и не очень) планы. KMM понравился, поэтому будем пошагово ковырять. Есть ощущение, что за этим будущее, но поглядим. Создал репу: https://github.com/Djangist/ToDoApp в которой будем делать кроссплатформенный Todo App…»
Уже совсем скоро стартует бесплатная онлайн-конфа от Яндекса: https://yatalks.yandex.ru/
Надеюсь будет интересно!
Надеюсь будет интересно!
yatalks.yandex.ru
YaTalks 2023 — Yandex's premier conference for the IT community
On December 5-6, Moscow and Belgrade will host over 100 IT industry experts and scientists delivering technical presentations on development, ML, and giving popular science lectures.
Ого!
Только мы недавно вспоминали Compose Multiplatform, как JetBrains анонсировали выход версии 1.0:
https://blog.jetbrains.com/kotlin/2021/12/compose-multiplatform-1-0-is-going-live/
Только мы недавно вспоминали Compose Multiplatform, как JetBrains анонсировали выход версии 1.0:
https://blog.jetbrains.com/kotlin/2021/12/compose-multiplatform-1-0-is-going-live/
The JetBrains Blog
Compose Multiplatform 1.0 Is Going Live! | The Kotlin Blog
Compose Multiplatform by JetBrains, the declarative UI framework for Kotlin, has reached version 1.0, which makes it ready for production use! Here are a few highlights that we hope will make you as e
Принцип проектирования по контракту
Бертран Мейер разработал принцип проектирования по контракту для языка Eiffel. Это простая, но эффективная методика, направленная на документирование (и согласование) прав и обязанностей программных модулей, чтобы обеспечить правильность программы. А что такое правильная программа? Это программа, которая выполняет только то, что от нее требуется, - ни больше и ни меньше. Документирование и верификация такого требования и составляет саму суть проектирования по контракту.
Каждая функция и метод в программной системе выполняет какое-то действие. Прежде чем начать это действие, функция может предполагать какое-то состояние окружающего мира, а по завершении она может сделать заявление о состоянии окружающего мира (перевод на русский, вероятно, не самый удачный, но суть отражает). Эти предположения и требования Мейер описывает следующим образом.
- Предусловия. Это требования подпрограммы, которые определяют, что должно быть истинным для ее вызова. Подпрограмма вообще не должна вызываться, если ее предусловия будут нарушены.
- Постусловия. Это состояние окружающего мира по завершении подпрограммы, т.е. То, что ею гарантируется. Наличие постусловия у подпрограммы подразумевает, что она непременно завершится, а следовательно, бесконечные циклы не допускаются.
- Инварианты класса. Класс гарантирует, что данное условие для вызывающего кода всегда истинно. В процессе внутренней обработки в подпрограмме инвариант может и не соблюдаться, но к моменту выхода из подпрограммы и передачи управления вызывающему коду инвариант должен быть непременно истинным.
Таким образом, контракт между подпрограммой и любым потенциально вызывающим кодом может быть составлен следующим образом.
- Если все предусловия подпрограммы удовлетворяются вызывающим кодом, то подпрограмма гарантирует истинность всех постусловий и инвариантов при своем завершении.
К чему это все?
Оказывается, в Kotlin 1.3 появился пакет kotlin.contracts и у нас есть возможность попробовать использовать этот принцип на практике, делая наши приложения более документированными и безопасными.
А вот примеры использования этого пакета: https://blog.kotlin-academy.com/understanding-kotlin-contracts-f255ded41ef2
Кстати, а вы слышали про подобный принцип проектирования ранее?
Бертран Мейер разработал принцип проектирования по контракту для языка Eiffel. Это простая, но эффективная методика, направленная на документирование (и согласование) прав и обязанностей программных модулей, чтобы обеспечить правильность программы. А что такое правильная программа? Это программа, которая выполняет только то, что от нее требуется, - ни больше и ни меньше. Документирование и верификация такого требования и составляет саму суть проектирования по контракту.
Каждая функция и метод в программной системе выполняет какое-то действие. Прежде чем начать это действие, функция может предполагать какое-то состояние окружающего мира, а по завершении она может сделать заявление о состоянии окружающего мира (перевод на русский, вероятно, не самый удачный, но суть отражает). Эти предположения и требования Мейер описывает следующим образом.
- Предусловия. Это требования подпрограммы, которые определяют, что должно быть истинным для ее вызова. Подпрограмма вообще не должна вызываться, если ее предусловия будут нарушены.
- Постусловия. Это состояние окружающего мира по завершении подпрограммы, т.е. То, что ею гарантируется. Наличие постусловия у подпрограммы подразумевает, что она непременно завершится, а следовательно, бесконечные циклы не допускаются.
- Инварианты класса. Класс гарантирует, что данное условие для вызывающего кода всегда истинно. В процессе внутренней обработки в подпрограмме инвариант может и не соблюдаться, но к моменту выхода из подпрограммы и передачи управления вызывающему коду инвариант должен быть непременно истинным.
Таким образом, контракт между подпрограммой и любым потенциально вызывающим кодом может быть составлен следующим образом.
- Если все предусловия подпрограммы удовлетворяются вызывающим кодом, то подпрограмма гарантирует истинность всех постусловий и инвариантов при своем завершении.
К чему это все?
Оказывается, в Kotlin 1.3 появился пакет kotlin.contracts и у нас есть возможность попробовать использовать этот принцип на практике, делая наши приложения более документированными и безопасными.
А вот примеры использования этого пакета: https://blog.kotlin-academy.com/understanding-kotlin-contracts-f255ded41ef2
Кстати, а вы слышали про подобный принцип проектирования ранее?
Medium
Understanding Kotlin contracts
Since Kotlin 1.3 we can enjoy new, mysterious feature — Kotlin contracts. From the usage perspective, they look just like a piece of code…