Всем привет. А кто-ни будь сталкивался с java.lang.ClassCastException при обращении

к ProvidableCompositionLocal.current? Я уже второй день ковыряюсь и никак не могу создать минимальный пример демонстрирующий проблему - всё ломается исключительно в полном приложении. Выглядит это примерно так:
java.lang.ClassCastException: androidx.compose.runtime.ParcelableSnapshotMutableState cannot be cast to java.util.Map
В строке где я просто обращаюсь к current
val myIds = localIds.current
Значение localIds определено вот так:
private val localIds = compositionLocalOf<Map<Long, String>> {
error("Ids are not available")
}
Т.е. оно откуда-то берёт значение типа ParcelableSnapshotMutableState и пытается кастить его в Map<Long, String>. Я залез в кишки композа уже и похоже там в currentCompositionLocalScope методе в строке:
val providers = providerUpdates[current]
?: reader.groupAux(current) as CompositionLocalMap
В каких-то ситуациях (ошибка не всегда возникает, но не рандомно) оно читает из reader.groupAux(current) что-то совершенно не соответствующее тому что должно там лежать. Где и как оно его туда кладёт я не нашёл. Эта проблема возникает только если функция обращающаяся к localIds.current лежит внутри LazyColumn (ну т.е. элемент списка) и только когда компонент начинает уходить из композиции во время анимации. В месте выше по стеку где я делаю
CompositionLocalProvider(
localId provides mapOf(1L to "heheh")
...
){
...
}
Я вставил логирование и вижу что значение правильное. Более того, если я обращаюсь к этой переменной одним (ну примерно) "фреймом" выше по стеку - всё нормально, вот примерно так:
...
val myIds1 = localIds.current // это нормально срабатывает
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(
items = items,
key = { item -> item.toString() }
) { element ->
val myIds = localIds.current // a это падает с ошибкой
...
}
}
...
Кто-нибудь может предположить в чём тут дело? Или может сталкивался?

8 ответов

26 просмотров
Agry-Gami Автор вопроса

Всем привет снова :) Я опять про свою проблему хочу у общественности спросить. Я сделал вроде как минимальный пример который демонстрирует похожую или, как мне кажется, связанную багу вот тут: https://gist.github.com/AngryGami/a83d0fe7f0a3d6968bb43a401bec7999 При нажатии на кнопку внизу экрана приложение падает с java.lang.IllegalStateException: nope 2 Т.е. значение не провайдится как будто, хотя bottomBar композабл находится внутри соответствующего CompositionLocalProvider (первый экран ведь работает хотя он делает в точности то же самое). Если заменить Scaffold на PoorManScaffold - всё опять начинает работать. Т.е. Scaffold каким-то образом теряет контекст внешнего CompositionLocalProvider и только для bottomBar`а. Кто-нибудь знает почему это происходит? Бага ли это или ожидаемое поведение?

Agry Gami
Всем привет снова :) Я опять про свою проблему хоч...

Пробовал интереса ради вынести тело начиная от Scaffold в отдельную композабл?

Agry-Gami Автор вопроса
Konstantin Dovnar
Пробовал интереса ради вынести тело начиная от Sca...

Не понимаю что ты имеешь ввиду... Всё что внутри CompositionLocalProvider?

Agry Gami
Не понимаю что ты имеешь ввиду... Всё что внутри C...

Имею ввиду вынести вот эту часть в отдельную функцию.

Agry Gami
Неа, падает точно так же:

Ладно, это было ожидаемо, но стоило попробовать:)

Agry-Gami Автор вопроса
Agry-Gami Автор вопроса
Konstantin Dovnar
Ладно, это было ожидаемо, но стоило попробовать:)

https://gist.github.com/AngryGami/740220d9c510b10645ab17996c39de38 Вот ещё немного сузил круг подозреваемых. Дело не в Scaffold`е самом по себе - дело в том что если использовать CompositionLocalProvider внутри SubcomposeMeasureScope.subcompose оно начинает так себя вести. Стандартный Scaffold заворачивает bottomBar в такой вызов а основной контент не заворачивает, отсюда и проблема.

Похожие вопросы

Обсуждают сегодня

Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Вот еще странный косяк, подскажите как бороться. Я git clone сделал себе всего embassy и примеры там запускаю. Всё хорошо. Но вот решил в cargo.toml зависимости не как в приме...
Lukutin R2AJP
2
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Объясните, пожалуйста, почему компилятор ругается на использование в условии неинициализированной переменной: int x; Task.Run(async () => { x = await somefunc(); }).Wait...
Александр
5
Раз начали говорить про embassy, то присоединюсь со своими парой вопросов. 1) Есть ли сопоставимые аналоги для асинхронного кода в emdebbed? 2) Можно ли внутри задач embassy ...
NI_isx
6
Всем привет, нужна как никогда, нужна помощь с IO в загрузчике. Пишу в code16 после установки сегментных регистров, пишу вывод символа. Пробовал 2 варианта: # 1 mov $0x0E, %a...
Shadow Akira
14
Добрый вечер, Пока не совсем понимаю как наладить общение между телеграм ботом и ПО для работы с сим боксом. По самому боту так понял: - Нужен некий баланс, который можно поп...
Magic
6
Всем привет. Ребята, подскажите, пожалуйста. у ботов есть ограничение на отправку сообщений - 30 сообщений в секунду, эти ограничения накладываются на все сообщения? или на со...
Artem Stormageddon
4
Блин, ребята, сори за тупые вопросы. А можно ли как-то открыть вебапку по нажатию на кнопку в меню(которое появляется слева, команды)?
Artem Stormageddon
3
Коллеги, я тут для личных нужд пошел ставить MQTT сервер, пощупал mosquitto, но ужаснулся отсутствию такой банальности, как HTTP API для посмотреть список топиков. А тут что,...
Maksim Lapshin
14
Карта сайта