Как я могу вернуть результат из базы данных Room потокобезопасным способом?Android

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

Сообщение Anonymous »

Я хочу реализовать запрос, который возвращает результат. Android требует, чтобы этот тип запроса выполнялся в отдельном потоке, чтобы избежать блокировки потока пользовательского интерфейса.
Мой код основан на руководстве https://iifx.dev/en/articles/457770601/ ... p-tutorial. В этом руководстве не рассматривается запрос, который возвращает результат в некомпонуемом контексте. Он использует функциональность Kotlin Flow для возврата данных, но собирает данные с помощью CollectAsState(), который может быть реализован только в составной функции.
Я хотел бы собрать данные в функции обработчика событий для переключателя, который является несоставной функцией и поэтому рисует ошибку с помощью CollectAsState(). Обработчик событий обновляет переменную State, которая вызывает заполнение текстового поля пользовательского интерфейса.
Информация на странице https://developer.android.com/training/ ... nc-queries предполагает, что правильный способ реализации одноразового запроса — это использование сопрограмм Kotlin и функций приостановки.
Итак, как мне собрать результаты функции приостановки в некомпонуемом событии обработчик?
Вот соответствующий код. Этот код, когда он будет завершен, скомпилируется и запустится. при нажатии переключателя заполняются только инициализированные значения, а не желаемые результаты базы данных.
@Entity(tableName = "travel_destinations")
data class TravelDestination(
@PrimaryKey(autoGenerate = true) val id: Int = 0,
val name: String,
val country: String,
)

@Dao
interface TravelDestinationDao {
@Query("SELECT * FROM travel_destinations")
fun geAllDestinations(): Flow

@Query("SELECT * FROM travel_destinations WHERE id = :idx")
fun getOneDestination(idx: Int): Flow

@Query("SELECT * FROM travel_destinations WHERE id = :idx")
suspend fun getOneDestinationx(idx: Int): TravelDestination
}

В классе модели представления getOneDestinationSuspend предназначен для реализации запуска/приостановки. Функция getOneDestination предназначена для реализации потока.
class TravelDestinationViewModel(private val destinationDao: TravelDestinationDao) : ViewModel() {
val allDestinations = destinationDao.geAllDestinations()

fun getOneDestination(destinationId: Int): Flow {
val destination: Flow = destinationDao.getOneDestination(destinationId)
return destination
}

fun getOneDestinationSuspend(destinationId: Int): TravelDestination {
var destinationx: TravelDestination = TravelDestination(0, "update initial", "")
viewModelScope.launch {
val destination: TravelDestination = destinationDao.getOneDestinationx(destinationId)
destinationx = destination
}
return destinationx
}
}

А вот как используется модель представления:
@Composable
fun TravelDestinationUpdate(
viewModel: TravelDestinationViewModel,
) {
var name by remember { mutableStateOf("") }
var country by remember { mutableStateOf("") }
val destinations by viewModel.allDestinations.collectAsState(initial = emptyList())
val options = destinations
val (selectedOption, onOptionSelected) = remember { mutableIntStateOf(0) }

Column {
TextField(value = name, onValueChange = { name = it }, label = { Text("Destination") })
TextField(value = country, onValueChange = { country = it }, label = { Text("Country") })

Column(Modifier.selectableGroup()) {
options.forEach { option ->
Row(
Modifier
.selectable(
selected = (option.id == selectedOption),
onClick = {
onOptionSelected(option.id)
val travelDestination =
viewModel.getOneDestinationSuspend(option.id)
name = travelDestination.name
country = travelDestination.country
},
role = Role.RadioButton,
)
) {
RadioButton(
selected = (option.id == selectedOption),
onClick = null, // Accessibility best practice
)

Text(option.name + " " + option.country)
}
}
}
}
}


Подробнее здесь: https://stackoverflow.com/questions/798 ... d-safe-way
Ответить

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

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

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

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

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