uk
Feedback
Полуночные Зарисовки

Полуночные Зарисовки

Відкрити в Telegram

Моментами пишу о мыслях, Android и Kotlin ЛС: @secundans

Показати більше
219
Підписники
Немає даних24 години
Немає даних7 днів
Немає даних30 днів

Триває завантаження даних...

Схожі канали
Немає даних
Виникли проблеми? Будь ласка, оновіть сторінку або зверніться до нашого support-менеджера.
Хмара тегів
Немає даних
Виникли проблеми? Будь ласка, оновіть сторінку або зверніться до нашого support-менеджера.
Вхідні та вихідні згадування
---
---
---
---
---
---
Залучення підписників
вересень '24
вересень '24
+50
в 0 каналах
серпень '240
в 0 каналах
Get PRO
липень '240
в 0 каналах
Get PRO
червень '240
в 0 каналах
Get PRO
травень '24
+43
в 0 каналах
Get PRO
квітень '240
в 1 каналах
Get PRO
березень '24
+176
в 0 каналах
Дата
Залучення підписників
Згадування
Канали
25 вересня+1
24 вересня+4
23 вересня+4
22 вересня+32
Дописи каналу
2
Organizing Components in Jetpack Compose: Troubleshooting
0
3
Безболезненное перемещение ресурсов в мире нетранзитивных R-классов
0
4
Подлодка Тут относительно недавно был сезон про оптимизации UI. О своих впечатлениях и о том, что интересного подчерпнул, написал в чате @devex_and_dpe Podlodka Android Crew #11
0
5
Секрет Parcelable
0
6
(Не)стандартные способы передачи больших данных в Intent
0
7
Организация компонентов в Jetpack Compose: Еще один вариант
0
8
Организация компонентов в Jetpack Compose
0
9
С большим опозданием, но все же опубликовал исходный код с доклада. Там самые разные компиляторные плагины, такие как: - подсветка рекомпозиций - логирование причин рекомпозиций - удаление вызовов функции sourceInformation - генерация/удаление/отображение testTag - анализ стабильности параметров composable функций Все компиляторные плагины подключаются к проекту как gradle plugin. Можно все по отдельности, а можно вместе - так удобнее настраивать. В проверках стабильности параметров поддержаны самые последние обновления Compose Compiler, а именно возможность задавать в файле классы, которые надо пропустить в проверках. Подробнее писали тут. Кроме этого есть ещё idea plugin. Правда в виде jar, так как получил отказ при попытке публикации в JetBrains Marketplace. Он умеет отображать какие testTag будут сгенерированы компиляторным плагином, а так же проверять стабильность параметров функций и отображать ошибку в редакторе кода. Конечно, не на 100%, как это в компиляторном плагине сделано, но, думаю, в большинстве случаев правильно. Ну и получил несколько просьб по поводу detekt правила для проверки параметров функций. Его тоже добавил. И там же есть возможность исключать классы, которые не нужно проверять. Если будут проблемы или вопросы - пишите. Попробуем решить) github.com/VKCOM/vkompose
0
10
Как запустить активность без регистрации (и SMS) в манифесте?
0
11
А что там по issues? Из свежего нашел такой - как low priority штуку все таки будут фиксить. Почему тогда везде предлагают использовать ссылки на функцию? У меня есть несколько объяснений этому: 1. Никто просто не проверил и лычки staffов в крупных компаниях хорошо сработали :) 2. Возможно раньше, когда в Kotlin Compiler был старый backend, это работало, а эта рекомендация тянется с тех пор. Но потом когда на стримах компилятор переписывали на IR, то этот случай пропустили? Что же касается статьи, на которую много ссылок, то там же есть ссылка на github, где уже заведен одинокий issue на использование ссылки на функцию :) Upd. Пофикшено тут, но теперь следите за context recievers или включайте strong skipping mode)
0
12
На первой картинке код, который сгенерирует Compose Compiler. Все получается ровно так, как описывалось ранее: лямбда оборачи+2
На первой картинке код, который сгенерирует Compose Compiler. Все получается ровно так, как описывалось ранее: лямбда оборачивается в remember, а ссылка на функцию нет. Второй скриншот уже того, как это будет в байткоде (добавил еще аргумент со строкой для очевидности) И наконец то, как это может повлиять на практите. Compose ссылки на функцию проверяет не через equlas, а ссылочно, поэтому мы получаем (третий скриншот): 1. лишние рекомпозиции 2. лишнее создания ссылки на функцию на каждую рекомпозицию
0
13
Скинул свои находки коллегам, а в ответ мне скинули доклад уважаемых людей из ex-Twitter. Там 40ой минуте(или на 129 слайде)
Скинул свои находки коллегам, а в ответ мне скинули доклад уважаемых людей из ex-Twitter. Там 40ой минуте(или на 129 слайде) ровно такой же пример, но рекомендуют они использовать ссылки на функцию вместо лямбд. Показалось странным, но они ссылаются на статью еще одного уважаемого человека, где изначально была рекомендация. На эту же статью ссылаются еще две по оптимизациям в Compose: первая и вторая Произошел какой-то скам или я попал в матрицу? :) Давайте разбираться и доказывать.
0
14
Квиз закончился неоднозначно, поэтому попробую чуть подробнее описать, что будет в первом и втором случае. Начнем с того, что ViewModel стабильный, так как пустой и никакого стейта внутри не держит, а значит все оптимизации, которые генерирует, Compose будут работать. Разница будем именно в генерации кода для ссылки на функцию и лямбды, которые принимают аргументы. В данном случае value: Int Для ссылки на функцию ничего не сгенерируется. А вот лямбда будет обертнута в выражение. rember(viewModel) { { value -> viewModel.doAction(value) }} То есть в Compose, если лямбда захватывает переменные, то она будет оборачиваться в remember, если все захваченные переменные стабильные. Выражение: val modifier = Modifier val modifierProvider = { modifier.fillMaxSize() } Превратится в: val modifier = Modifier val modifierProvider = remember(modifier) { { modifier.fillMaxSize() } } Только потому что Modifier стабильный. В случае ссылки на функцию, если уберем value: Int в doAction class ViewModel { fun doAction() {...} } То мемоизация уже будет работать. А код сгенерируется следующий: remember(viewModel, { viewModel::doAction } Почему же так? Просто в Compose три года назад написали так, что если ссылка на функцию принимает аргументы, то она не оборачивается в remember. И там же коммент, что надо бы это поправить в будущем, но оно пока не наступило)
0
15
Немає тексту...
0
16
Небольшой квиз :) Как думаете, есть ли разница между лямбдой и ссылкой на функцию в качестве аргумента Composable функции?
0
17
Убийца Compose? Совсем недавно узнал, что Huawei делают аналог Compose Multiplatform в виде нового декларативного фреймворка arkUI. Я хотел попробовать, но на сайте все ну прям очень пусто. Просто немного скриншотов не сильно хорошего качества. Ещё я узнал от HR из Huawei, что на проект они захантили лидов Compose Multiplatform из JB. Но пока отнесся к этому со скепсисом, так как никаких официальных заявлений нету и у этих лидов в linkedin все ещё висит, что место работы JB. Изначально предположил, что это будет форк Compose Multiplatform. Например, DevEco Studio, который является форком то ли IntelliJ Idea, то ли Android Studio. Но HR говорит, что проект прям с нуля, но будет продолжать идеи Compose Multiplatform, хоть основным языком будет Js/Ts. В общем жду. Будет интересно глянуть)
0
18
Третий кейс. Класс стабильный, но internal и лежит в другом файле, но при инкрементальной компиляции становится нестабильным, а функция, которая имела возможность пропуска рекомпозиции, большее её не имеет. Четвёртый кейс. Та же ситуация с классом, но в случае мемоизации лямбды. Класс был стабилен при чистой сборке и мемоизация работала, а теперь точно не работает, потому что internal класс стал unstable. Собрав все свои наработки сделал PR в Compose Compiler, а потом перенёс его в android review, из-за отсутствия активности на GitHub. Но тут большое спасибо Андрею Шикову, который проревьюил. Большинство моих фиксов ломали бинарную совместимость, поэтому фиксить будет команда компилятора сама. Первый фикс: Теперь аннотация @StabilityInferred будет добавляться и для internal классов, а в добавок, чтобы не даунгрейдить определение стабильности класса из stable до runtime stable, добавится аннотация @KnownStability Второй фикс (скорее фича): Появится возможность самому регулировать степень мемоизации лямбд и сохранять их, даже если они захватывают что-то нестабильное. Кроме того, можно будет зафорсить пропускаемость функции, даже если параметры функции нестабильные. А потом отдельной аннотацией @NonSkippableComposable выборочно отключать эту штуку для конкретных функций. Мне понравились такие классные решения, поэтому свернул свои изменения. Но эти изменения ещё не влиты и возможно что-то поменяется. Но некоторые фиксы, которые лежали на поверхности, не касались инкрементальной компиляции и ничего особо не ломали, все таки смог влить. Проблема генерации $stable для combined stable классов. Да, все это время эта штука не работала из-за небольшого бага) Combined stable - это такой тип стабильности, когда она определяется через стабильность нескольких классов, которые используются в одном классе. В $stable в таком случае не может лежать какое то определённое значение, а должно было генерироваться логическое сложение $stable полей используемых классов. Мемоизация работала для function reference, у которых extension reciever нестабильный. Это не совсем правильно, а про reciever я писал тут.
0
19
Инкрементальная компиляции в Compose Compiler. Что может пойти не так? Погружаясь в исходники компилятора компоуза никогда не думал, что может возникнуть проблема с инкрементальной компиляцией. Но как-то изучая причины, по которым Compose Compiler определяет стабильность типов и то, как использует их в дальнейшей генерации - начали появляться сомнения, что все действительно гладко. Начну с известного: Compose Compiler любезно определяет стабильность классов даже если не проставить @Stable и @Immutable на самом деле это одно и то же на данный момент, проставляя аннотацию @StabilityInferred. Но этим польза @StabilityInferred не заканчивается. Дело в том, что gradle модули компилируются, грубо говоря, изолировано друг от друга, поэтому компиляторный плагин при инкрементальной компиляции не может получить абсолютно всю информацию о содержимом классов/функции из другого модуля. Например, не получится вытащить body или переменные сгенерированные (я проверял). То есть доступно только stub отображение класса. Соответственно, нужно размечать классы в других модулях, чтобы повторно не пытаться определять стабильность класса с меньшим количеством информации, чем оно было доступно при полной компиляции. Но тут есть две проблемы (или особенности): 1) @StabilityInferred вешается (сюрприз) и на нестабильные классы. А информация о нестабильности или стабильности будет лежать в поле val $stable: Int 2) Аннотация вешается только на публичные классы Чтобы понять к чему могут привести эти особенности, нужно копнуть немного глубже в понятие стабильности в компиляторе. В Compose Compiler не ограничивается опеределением того, что класс стабильный или нестабильный. Есть ещё несколько вариантов описания стабильности, но концептуально можно разделить на три: 1. Stable 2. Unstable 3. Runtime stable Если с первыми двумя все понятно, то третий говорит о том, что стабильность класса не определена и это скорее произойдет в runtime, а как это произойдёт совсем другая история. Runtime stable может быть класс: 1. Есть используются generic'и 2. Если он из другого модуля в виде stub и помечен аннотацией @StabilityInferred Но в Compose Compiler используют runtime stable в разных случаях и по разному. В одних случаях он трактуется как стабильный, а в других как нестабильный. Например. Для мемоизации лямбд важно, чтобы класс был точно стабильным, а runtime stable трактуется как unstable. А вот для генерации возможности пропуска функции во время рекомпозиции важно, важно, чтоб класс не был unstable, то есть runtime stable в этом случае приравнивается к stable. В итоге, суммируя вышесказанное, получаем первый кейс с багом для инкрементальной компиляции. Первый кейс. Класс лежит в другом модуле и он стабилен, но публичный, а значит пометился аннотацией @StabilityInferred и для текущего модуля является runtime stable. Текущий модуль компилируется и перед тем как обернуть лямбду в remember, смотрит: а не захватывается ли чего нестабильного? В данном случае runtime stabe == unstable, поэтому лямбда не будет сохраняться между рекомпозициями, хотя при чистой сборке сохранялась. Второй кейс скорее положительный. Допустим класс из другого модуля нестабильный и используется аргументах @Composable функции, а значит он будет расцениваться как stable и сгенерируется возможность пропуска рекомпозиции, хотя её не было при чистой сборке. Ситуация становится ещё более неочевидной, если учесть, что инкрементальная компиляция работает не только на уровне gradle модулей, но и kotlin файлов и кейсы выше будут так же верны и для случаев, когда функция и класс находятся в разных файлах. Ну и не забываем, что @StabilityInferred проставляется только для публичных классов, а в модуле могут быть ещё internal классы, которые будут stub'ами при инкрементальной компиляции. А Compose Compiler помечает stub'ы как unstable, если нету аннотации. В итоге получаем ещё новые баги.
0
20
Mobius Информации, которую нарыл по компиляторным плагинам и, в частности, по frontend плагинам оказалось достаточно, чтобы доклад прошёл ревью. Из интересного, что проекты, которые буду приводить в качестве примеров использования компиляторных плагинов, содержат ещё idea и gradle плагины. Не хватает flipper плагина для полного набора) https://mobiusconf.com/talks/0beebbbd16bf4358ab2a1b60cabf57a1/
0