Ошибка:
Recomposer.applyAndCheck
java.lang.IllegalStateException — неподдерживаемое одновременное изменение во время композиции. Объект состояния был изменен в результате композиции, а также изменен вне композиции.
Время от времени у меня возникает ошибка с неподдерживаемым одновременным изменением.
Я пытаюсь понять источник проблемы. Когда я изучал компоновку, я использовал coroutineScope с Dispatchers.IO для обновления состояния, и это вызывало ту же проблему. Я прочитал https://developer.android.com/develop/u ... de-effects и не вижу никаких проблем в своем коде.
Что это за проблема? ?
Может быть, во время изменений состояния мне следует использовать viewModelScope?
is HomeEvent.OnFreeCouponDeclined -> {
homeState.update {
copy(isDeclined = false)
}
}
должно быть?
is HomeEvent.OnFreeCouponDeclined -> {
viewModelScope.launch {
homeState.update {
copy(isDeclined = false)
}
}
}
Может быть, здесь что-то не так?
private fun observeInventory() {
viewModelScope.launch {
(Dispatchers.Default) {
getInventoryInteractor.invoke().collectLatest {
(Dispatchers.Main) {
homeState.value = homeState.value.copy(categories = it.map {
it.copy(subCategories = emptyList())
})
}
}
}
}
}
Похоже, я иногда использую viewModelScope для изменения состояния, а иногда нет.
Пожалуйста, прошу у вас совета, на что мне следует обратить внимание?
Может быть, этот код?
LaunchedEffect("${state.currentPage}_${sliderHoldTimestamp}_${sliderItems.size}") {
delay(AUTO_SLIDER_DELAY)
coroutineScope.launch {
if (sliderItems.isNotEmpty() && state.pageCount != 0) {
var newPosition = state.currentPage + 1
if (newPosition > sliderItems.size - 1) newPosition = 0
state.animateScrollToPage(newPosition.mod(state.pageCount))
}
}
}
Это автоматический слайдер, мне пришлось обойти его таким образом из-за перехода от аккомпаниатора к более новому подходу.
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
const val foundation = "androidx.compose.foundation:foundation:1.6.1"
EDIT1:
private var _homeState = MutableStateFlow(HomeState(isAddressAddedFromOnboarding))
val homeState: StateFlow = _homeState
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(4000L),
initialValue = HomeState(isAddressAddedFromOnboarding)
)
private fun checkIsActiveOrder() {
viewModelScope.launch {
isActiveOrderInDeliveryInteractor.invoke().collectLatest {
_homeState.value = _homeState.value.copy(isActiveOrder = it)
}
}
}
Or with val _homeState
_homeState.update {
copy(isNotificationPermissionAsked = it)
}
Как вы предлагаете обновить эти данные? У меня много таких коллекционеров. Вы предлагаете объединить около 10 ~? Могу ли я просто скопировать и собрать его, как раньше? Но с новым подходом HomeScreen.
Я использую расширение:
infix fun MutableStateFlow.update(updater: T.() -> T) {
this.value = updater(this.value)
}
EDIT2:
[...]
: ViewModel() {
private val _homeState = MutableStateFlow(HomeState(isAddressAddedFromOnboarding))
val homeState: StateFlow = _homeState.asStateFlow()
init {
viewModelScope.launch {
combine(
getAccountTypeInteractor.invoke(),
getDeliveryEstimatedTimeInteractor.invoke(),
getInventoryInteractor.invoke(),
getSliderItemsInteractor.invoke(),
getBestSellersProductsInteractor.invoke(),
getSpecialCategoriesInteractor.invoke(),
getCurrentAddressInteractor.invoke(),
getVerificationAgeStateInteractor.invoke(),
getIsNewDarkStoreSyncInteractor.invoke(),
getAdditionalMenuOptionsInteractor.invoke(),
getBasketTotalValueWithoutDiscountInteractor.invoke(),
checkIsStoriesDataLoadedInteractor()
) { accountType, deliveryEstimatedTime, inventory, sliders, bestSellers, specialCategories, currentAddress, ageVerificationState, isLoading, additionalMenuOptions, basketTotalValueWithoutDiscount, storiesDataLoaded, ->
// it doesn't log anything, not even null
Log.d("homeStateVALUES", """
accountType: $accountType,
deliveryEstimatedTime: $deliveryEstimatedTime,
inventory: $inventory,
sliders: $sliders,
bestSellers: $bestSellers,
specialCategories: $specialCategories,
currentAddress: $currentAddress,
ageVerificationState: $ageVerificationState,
isLoading: $isLoading,
additionalMenuOptions: $additionalMenuOptions,
basketTotalValueWithoutDiscount: $basketTotalValueWithoutDiscount,
storiesDataLoaded: $storiesDataLoaded
""")
HomeState(
isAddressAddedFromOnboarding = isAddressAddedFromOnboarding,
isLogged = accountType == AccountType.STANDARD_ACCOUNT,
chipTime = deliveryEstimatedTime,
categories = inventory.map {
it.copy(subCategories = emptyList())
},
sliderItems = sliders,
bestsellers = bestSellers,
specialCategories = specialCategories,
currentAddress = currentAddress,
ageVerificationState = ageVerificationState,
isLoading = isLoading,
additionalMenuOptions = additionalMenuOptions,
basketTotalValueWithoutDiscount = basketTotalValueWithoutDiscount,
storiesDataLoaded = storiesDataLoaded
)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(1000L),
initialValue = _homeState.value
)
}
}
onTriggeredEvent~
is HomeEvent.OnFreeCouponAccepted -> {
viewModelScope.launch {
_homeState.updateFlow {
copy(isAddressAddedFromOnboarding = false)
}
}
}
HomeScreen
fun HomeScreen(
state: StateFlow // I'm using here viewModel.homeState
) {
val homeState by state.collectAsStateWithLifecycle()
Здесь это не работает. Я не могу загрузить свои данные.
Edit3:
@Composable
fun HomeScreen() {
val scaffoldState = rememberScaffoldState()
val screenHeightDp = LocalConfiguration.current.screenHeightDp.dp
val screenWidthDp = LocalConfiguration.current.screenWidthDp.dp
val screenHeight by remember { mutableStateOf(screenHeightDp) }
val screenWidth by remember { mutableStateOf(screenWidthDp) }
val listState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
[...]
@Composable
fun DoubleBackToLeaveApp(drawerState: DrawerState) {
val doubleBackToExitPressedOnce = remember { mutableStateOf(true) }
val backScope = rememberCoroutineScope()
val backContext = LocalContext.current
BackHandler(doubleBackToExitPressedOnce.value) {
[...]
Компонуемый элемент, используемый в HomeScreen
@Composable
fun DoubleBackToLeaveApp(drawerState: DrawerState) {
val doubleBackToExitPressedOnce = remember { mutableStateOf(true) }
val backScope = rememberCoroutineScope()
val backContext = LocalContext.current
Этот пример неправильный? Может ли это вызвать эту ошибку? Здесь состояние создается в компонуемой форме, и в то же время у меня есть логика в viewModel с моим внешним состоянием.
Должен ли я изменить ее на:
@Composable
fun DoubleBackToLeaveApp(
drawerState: DrawerState,
doubleBackToExitPressedOnce: MutableState, // take care in my HomeState as other params?
backScope: CoroutineScope
) {
val backContext = LocalContext.current
Еще один пример, здесь по-вашему неправильно? isAsked создается в @Composable, поэтому мне снова следует использовать HomeState и доставить его этому компоненту, верно?
@OptIn(ExperimentalComposeUiApi::class, ExperimentalPermissionsApi::class)
@Composable
fun TurnNotificationOn(
onFinish: () -> Unit
) {
val NotificationPermissionState: PermissionState
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
notificationPermissionState = rememberPermissionState(
Manifest.permission.POST_NOTIFICATIONS
)
} else {
onFinish()
return
}
val isAsked = remember { mutableStateOf(false) }
LaunchedEffect(notificationPermissionState.status) {
if (isAsked.value) {
onFinish()
}
isAsked.value = true
}
Подробнее здесь: https://stackoverflow.com/questions/785 ... omposition
Как исправить «Неподдерживаемое одновременное изменение во время композиции»? ⇐ Android
Форум для тех, кто программирует под Android
1716969513
Anonymous
Ошибка:
Recomposer.applyAndCheck
java.lang.IllegalStateException — неподдерживаемое одновременное изменение во время композиции. Объект состояния был изменен в результате композиции, а также изменен вне композиции.
Время от времени у меня возникает ошибка с неподдерживаемым одновременным изменением.
Я пытаюсь понять источник проблемы. Когда я изучал компоновку, я использовал coroutineScope с Dispatchers.IO для обновления состояния, и это вызывало ту же проблему. Я прочитал https://developer.android.com/develop/ui/compose/side-effects и не вижу никаких проблем в своем коде.
Что это за проблема? ?
Может быть, во время изменений состояния мне следует использовать viewModelScope?
is HomeEvent.OnFreeCouponDeclined -> {
homeState.update {
copy(isDeclined = false)
}
}
должно быть?
is HomeEvent.OnFreeCouponDeclined -> {
viewModelScope.launch {
homeState.update {
copy(isDeclined = false)
}
}
}
Может быть, здесь что-то не так?
private fun observeInventory() {
viewModelScope.launch {
(Dispatchers.Default) {
getInventoryInteractor.invoke().collectLatest {
(Dispatchers.Main) {
homeState.value = homeState.value.copy(categories = it.map {
it.copy(subCategories = emptyList())
})
}
}
}
}
}
Похоже, я иногда использую viewModelScope для изменения состояния, а иногда нет.
Пожалуйста, прошу у вас совета, на что мне следует обратить внимание?
Может быть, этот код?
LaunchedEffect("${state.currentPage}_${sliderHoldTimestamp}_${sliderItems.size}") {
delay(AUTO_SLIDER_DELAY)
coroutineScope.launch {
if (sliderItems.isNotEmpty() && state.pageCount != 0) {
var newPosition = state.currentPage + 1
if (newPosition > sliderItems.size - 1) newPosition = 0
state.animateScrollToPage(newPosition.mod(state.pageCount))
}
}
}
Это автоматический слайдер, мне пришлось обойти его таким образом из-за перехода от аккомпаниатора к более новому подходу.
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
const val foundation = "androidx.compose.foundation:foundation:1.6.1"
EDIT1:
private var _homeState = MutableStateFlow(HomeState(isAddressAddedFromOnboarding))
val homeState: StateFlow = _homeState
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(4000L),
initialValue = HomeState(isAddressAddedFromOnboarding)
)
private fun checkIsActiveOrder() {
viewModelScope.launch {
isActiveOrderInDeliveryInteractor.invoke().collectLatest {
_homeState.value = _homeState.value.copy(isActiveOrder = it)
}
}
}
Or with val _homeState
_homeState.update {
copy(isNotificationPermissionAsked = it)
}
Как вы предлагаете обновить эти данные? У меня много таких коллекционеров. Вы предлагаете объединить около 10 ~? Могу ли я просто скопировать и собрать его, как раньше? Но с новым подходом HomeScreen.
Я использую расширение:
infix fun MutableStateFlow.update(updater: T.() -> T) {
this.value = updater(this.value)
}
EDIT2:
[...]
: ViewModel() {
private val _homeState = MutableStateFlow(HomeState(isAddressAddedFromOnboarding))
val homeState: StateFlow = _homeState.asStateFlow()
init {
viewModelScope.launch {
combine(
getAccountTypeInteractor.invoke(),
getDeliveryEstimatedTimeInteractor.invoke(),
getInventoryInteractor.invoke(),
getSliderItemsInteractor.invoke(),
getBestSellersProductsInteractor.invoke(),
getSpecialCategoriesInteractor.invoke(),
getCurrentAddressInteractor.invoke(),
getVerificationAgeStateInteractor.invoke(),
getIsNewDarkStoreSyncInteractor.invoke(),
getAdditionalMenuOptionsInteractor.invoke(),
getBasketTotalValueWithoutDiscountInteractor.invoke(),
checkIsStoriesDataLoadedInteractor()
) { accountType, deliveryEstimatedTime, inventory, sliders, bestSellers, specialCategories, currentAddress, ageVerificationState, isLoading, additionalMenuOptions, basketTotalValueWithoutDiscount, storiesDataLoaded, ->
// it doesn't log anything, not even null
Log.d("homeStateVALUES", """
accountType: $accountType,
deliveryEstimatedTime: $deliveryEstimatedTime,
inventory: $inventory,
sliders: $sliders,
bestSellers: $bestSellers,
specialCategories: $specialCategories,
currentAddress: $currentAddress,
ageVerificationState: $ageVerificationState,
isLoading: $isLoading,
additionalMenuOptions: $additionalMenuOptions,
basketTotalValueWithoutDiscount: $basketTotalValueWithoutDiscount,
storiesDataLoaded: $storiesDataLoaded
""")
HomeState(
isAddressAddedFromOnboarding = isAddressAddedFromOnboarding,
isLogged = accountType == AccountType.STANDARD_ACCOUNT,
chipTime = deliveryEstimatedTime,
categories = inventory.map {
it.copy(subCategories = emptyList())
},
sliderItems = sliders,
bestsellers = bestSellers,
specialCategories = specialCategories,
currentAddress = currentAddress,
ageVerificationState = ageVerificationState,
isLoading = isLoading,
additionalMenuOptions = additionalMenuOptions,
basketTotalValueWithoutDiscount = basketTotalValueWithoutDiscount,
storiesDataLoaded = storiesDataLoaded
)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(1000L),
initialValue = _homeState.value
)
}
}
onTriggeredEvent~
is HomeEvent.OnFreeCouponAccepted -> {
viewModelScope.launch {
_homeState.updateFlow {
copy(isAddressAddedFromOnboarding = false)
}
}
}
HomeScreen
fun HomeScreen(
state: StateFlow // I'm using here viewModel.homeState
) {
val homeState by state.collectAsStateWithLifecycle()
Здесь это не работает. Я не могу загрузить свои данные.
Edit3:
@Composable
fun HomeScreen() {
val scaffoldState = rememberScaffoldState()
val screenHeightDp = LocalConfiguration.current.screenHeightDp.dp
val screenWidthDp = LocalConfiguration.current.screenWidthDp.dp
val screenHeight by remember { mutableStateOf(screenHeightDp) }
val screenWidth by remember { mutableStateOf(screenWidthDp) }
val listState = rememberLazyListState()
val coroutineScope = rememberCoroutineScope()
[...]
@Composable
fun DoubleBackToLeaveApp(drawerState: DrawerState) {
val doubleBackToExitPressedOnce = remember { mutableStateOf(true) }
val backScope = rememberCoroutineScope()
val backContext = LocalContext.current
BackHandler(doubleBackToExitPressedOnce.value) {
[...]
Компонуемый элемент, используемый в HomeScreen
@Composable
fun DoubleBackToLeaveApp(drawerState: DrawerState) {
val doubleBackToExitPressedOnce = remember { mutableStateOf(true) }
val backScope = rememberCoroutineScope()
val backContext = LocalContext.current
Этот пример неправильный? Может ли это вызвать эту ошибку? Здесь состояние создается в компонуемой форме, и в то же время у меня есть логика в viewModel с моим внешним состоянием.
Должен ли я изменить ее на:
@Composable
fun DoubleBackToLeaveApp(
drawerState: DrawerState,
doubleBackToExitPressedOnce: MutableState, // take care in my HomeState as other params?
backScope: CoroutineScope
) {
val backContext = LocalContext.current
Еще один пример, здесь по-вашему неправильно? isAsked создается в @Composable, поэтому мне снова следует использовать HomeState и доставить его этому компоненту, верно?
@OptIn(ExperimentalComposeUiApi::class, ExperimentalPermissionsApi::class)
@Composable
fun TurnNotificationOn(
onFinish: () -> Unit
) {
val NotificationPermissionState: PermissionState
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
notificationPermissionState = rememberPermissionState(
Manifest.permission.POST_NOTIFICATIONS
)
} else {
onFinish()
return
}
val isAsked = remember { mutableStateOf(false) }
LaunchedEffect(notificationPermissionState.status) {
if (isAsked.value) {
onFinish()
}
isAsked.value = true
}
Подробнее здесь: [url]https://stackoverflow.com/questions/78538070/how-to-fix-unsupported-concurrent-change-during-composition[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия