к 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 это падает с ошибкой
...
}
}
...
Кто-нибудь может предположить в чём тут дело? Или может сталкивался?
Всем привет снова :) Я опять про свою проблему хочу у общественности спросить. Я сделал вроде как минимальный пример который демонстрирует похожую или, как мне кажется, связанную багу вот тут: https://gist.github.com/AngryGami/a83d0fe7f0a3d6968bb43a401bec7999 При нажатии на кнопку внизу экрана приложение падает с java.lang.IllegalStateException: nope 2 Т.е. значение не провайдится как будто, хотя bottomBar композабл находится внутри соответствующего CompositionLocalProvider (первый экран ведь работает хотя он делает в точности то же самое). Если заменить Scaffold на PoorManScaffold - всё опять начинает работать. Т.е. Scaffold каким-то образом теряет контекст внешнего CompositionLocalProvider и только для bottomBar`а. Кто-нибудь знает почему это происходит? Бага ли это или ожидаемое поведение?
Пробовал интереса ради вынести тело начиная от Scaffold в отдельную композабл?
Не понимаю что ты имеешь ввиду... Всё что внутри CompositionLocalProvider?
Имею ввиду вынести вот эту часть в отдельную функцию.
Неа, падает точно так же:
Ладно, это было ожидаемо, но стоило попробовать:)
Куры кончились - а идеи остались )))
https://gist.github.com/AngryGami/740220d9c510b10645ab17996c39de38 Вот ещё немного сузил круг подозреваемых. Дело не в Scaffold`е самом по себе - дело в том что если использовать CompositionLocalProvider внутри SubcomposeMeasureScope.subcompose оно начинает так себя вести. Стандартный Scaffold заворачивает bottomBar в такой вызов а основной контент не заворачивает, отсюда и проблема.
Обсуждают сегодня