Как предотвратить повторные вызовы UiState.Failure?Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Как предотвратить повторные вызовы UiState.Failure?

Сообщение Anonymous »

Я реализую LivenessScreen в Jetpack Compose с помощью следующего кода:
LivenessScreen(
viewModel = livenessViewModel,
onErrorScreen = onErrorScreen,
onLivenessComplete = onLivenessComplete
)

Проблема:
Когда я передаю onErrorScreen и onLivenessComplete в качестве лямбда-функций в LivenessScreen, случай UiState.Failure запускается несколько раз при следующих условиях:
  • При сбое API трижды запускается случай сбоя.
  • Когда я нажимаю кнопку «Назад» в системе, возникает случай сбоя. сработало снова.
Однако, когда я удаляю onErrorScreen и onLivenessComplete из параметров LivenessScreen, UiState.Failure запускается только один раз, когда API выходит из строя, и не запускается. снова при нажатии кнопки «Назад».
Наблюдения:
  • Из варианта использования состояние сбоя генерируется только один раз в соответствии с к журналы.
  • Повторяющиеся триггеры происходят только тогда, когда лямбда-выражения передаются в LivenessScreen.
Вопросы:< /p>
  • Что может быть причиной того, что случай UiState.Failure вызывается
    несколько раз?
  • Как я могу предотвратить повторное срабатывание состояния отказа при
    использовании лямбды в Jetpack Compose?
  • Существуют ли какие-либо передовые методы обработки лямбда-выражений и управления состоянием
    , чтобы избежать таких проблем?
Будем очень признательны за любую помощь или рекомендации!
MainActivity.kt
setContent {
val navController = rememberNavController()
NavGraph(navController)

}

NavGraph.kt
@Composable
fun NavGraph(navController: NavHostController) {
NavHost(
navController = navController, startDestination = NavRoute.LiveNess.path
) {
addLivenessScreen(navController, this)

addLiveNessSuccessScreen(navController, this)
}
}

fun addLivenessScreen(navController: NavHostController, navGraphBuilder: NavGraphBuilder) {
navGraphBuilder.composable(route = NavRoute.LiveNess.path) {
LivenessRoute(
onLivenessComplete = {
navController.navigate(NavRoute.LiveNessSuccess.path)
},
onErrorScreen = {
navController.navigate(NavRoute.GenericErrorScreen.path)
},
)
}
}

fun addLiveNessSuccessScreen(
navController: NavHostController,
navGraphBuilder: NavGraphBuilder,
config: SDKConfiguration
) {
navGraphBuilder.composable(route = NavRoute.LiveNessSuccess.path) {
LivenessSuccessScreen(
)
}
}

LivenessRoute.kt
@Composable
fun LivenessRoute(
onLivenessComplete: () -> Unit,
onErrorScreen: () -> Unit
) {
val livenessViewModel: LivenessViewModel = koinViewModel()
LivenessScreen(
viewModel = livenessViewModel,
onErrorScreen = onErrorScreen,
onLivenessComplete = onLivenessComplete
)
}

LivenessScreen.kt
@Composable
fun LivenessScreen(
modifier: Modifier = Modifier,
onLivenessComplete: () -> Unit,
onErrorScreen: () -> Unit,
viewModel: LivenessViewModel
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle()
V2Theme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Box(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),// Padding for better spacing
contentAlignment = Alignment.Center // Center content within the Box
) {
when (val state = uiState.value) {
is UiState.Loading -> {
Column(
horizontalAlignment = Alignment.CenterHorizontally, // Center items horizontally
verticalArrangement = Arrangement.Center // Center items vertically
) {
CircularProgressIndicator()
Spacer(modifier = Modifier.height(16.dp))
Text("Loading...")
}
}

is UiState.Success -> {
state.value?.sessionId?.let {
Column(
horizontalAlignment = Alignment.CenterHorizontally, // Center items horizontally
verticalArrangement = Arrangement.Center // Center items vertically
) {
CircularProgressIndicator()
Spacer(modifier = Modifier.height(16.dp))
Text("Loading... $it")
}
}
}

is UiState.Failure -> {
Log.d("FaceLivenessDetector", state.exception.toString())
}
}

}
}
}
}

LivenessViewModel.kt
class LivenessViewModel(private val fetchSessionDataUseCase: FetchSessionDataUseCase) :
ViewModel() {

private val _uiState = MutableStateFlow(UiState.Loading)
val uiState: StateFlow get() = _uiState

init {
fetchSessionData()
}

private fun fetchSessionData() {
val request = LivenessRequest(
kmsKeyId = null, // Optional
auditImagesLimit = 3, // Optional
clientRequestToken = generateRandomString(16) // Required
)
viewModelScope.launch {
fetchSessionDataUseCase.invoke(request).collectLatest { apiResult ->
when (apiResult) {
is ApiResult.Success -> {
_uiState.value = UiState.Success(apiResult.value)
}

is ApiResult.Failure -> {
_uiState.value = UiState.Failure(
apiResult.errorType ?: ApiException.UnknownError()
)
}

is ApiResult.Loading -> {
_uiState.value = UiState.Loading // Emit loading state
}
}
}
}

}
}

FetchSessionDataUseCase.kt
class FetchSessionDataUseCase(private val repository: LivenessRepository) {
operator fun invoke(request: LivenessRequest): Flow {
return flow {
try {
emit(Loading())
when (val result = repository.getSessionData(request)) {
is Failure -> {
emit(Failure(ApiException.UnknownError()))
}

is Success -> {
emit(result.mapSuccess {
Success(value)
})
}

else -> {
emit(Failure(ApiException.UnknownError()))
}
}

} catch (e: HttpException) {
emit(
Failure(
ApiException.NetworkError(
e.localizedMessage ?: "An unexpected error occurred."
)
)
)
} catch (e: IOException) {
emit(Failure(ApiException.NetworkError("Couldn't reach server. Check your internet connection.")))
}
}.catch { e ->
emit(Failure(ApiException.UnknownError("An error occurred: ${e.localizedMessage ?: "Unknown error"}")))
}
}
}

LivenessRepository.kt
interface LivenessRepository {
suspend fun getSessionData(request: LivenessRequest): ApiResult
}

LivenessRepositoryImpl.kt
class LivenessRepositoryImpl(
private val dataSource: LivenessRemoteDataSourceImpl
) : LivenessRepository {

override suspend fun getSessionData(request: LivenessRequest): ApiResult {
val apiResult = performRequest(
request = {
dataSource.getSessionData(
request
)
},
transform = { apiResponse ->
apiResponse.toDomainModel()
},
)
return apiResult
}

}


Подробнее здесь: https://stackoverflow.com/questions/793 ... lure-calls
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»