Я не являюсь экспертом в потоках сопрограмм, поэтому мне действительно нужна помощь. У меня есть две базы данных комнат в Android, т.е. UserData и UserProfileImage.
data class UserData(
val UserName : String,
val MobileNumber : String,
val tags : List<String>)
data class UserProfileImage(
val MobileNumber : String,
val ProfileUrl : String)
я создал два запроса для получения потока из обеих таблиц, например:
@Query("SELECT * FROM users_profile")
fun getUserProfileList() : Flow<List<UserProfileImage>>
@Query("SELECT * FROM users_data")
fun getUserDataList() : Flow<List<UserData>>
моя конечная цель - собрать данные из обеих таблиц и объединить их, как CombinedData (val UserName: String, val MobileNumber: String, val tags: List, val ProfileUrl: String) на основе значения "MobileNumber" и, наконец, показать их в recyclerview . как я могу объединить функции сбора, чтобы, если какая-либо из этих таблиц наблюдает какие-либо изменения в данных, тогда объединенные данные также должны обновляться, что в конечном итоге приводит к обновлению моего recyclerview. Заранее спасибо.
я читал о flatMapMerge, flatMapConcat и т. д., но не могу полностью понять, как именно я могу их использовать.
Лучшим подходом было бы избавиться от двух таблиц в первую очередь. Если у ваших пользователей есть только одно изображение, вы можете сохранить ссылку на изображение в пользовательской таблице. Если это не так, вы можете использовать оператор SQL JOIN для объединения таблиц. В этом случае ваша функция комнаты будет
@Query("SELECT * FROM UserData JOIN UserProfileImage ON UserData.MobileNumber = UserProfileImage.MobileNumber")
fun getUsersWithImages(): Flow<Map<UserData,List<UserProfileImage>>>
Это должно делать именно то, что вы хотите, без явного объединения Flow
s.
Однако, если вы все еще хотите сделать не в слое Room, это можно сделать следующим образом:
val usersFlow = getUserDataList()
val picturesFlow = getUserProfileList()
val mergedFlow: Flow<Map<UserData, List<UserProfileImage>>> = usersFlow.combine(picturesFlow) { users, profiles ->
val usersProfiles = profiles.groupBy { it.MobileNumber }
val result = buildMap {
for (user in users) {
put(user,usersProfiles[user.MobileNumber])
}
}
result
}
Вместо того, чтобы создавать два потока и объединять их позже, вы можете создать один поток с помощью отношений ROOMDB.
data class UserDataWithProfile(
@Embedded val userData: UserData,
@Relation(
parentColumn = "MobileNumber",
entityColumn = "MobileNumber"
)
val profileImage: UserProfileImage
)
И когда вы хотите запросить из ROOMDB, вы можете запросить поток пользовательских данных с изображением профиля, используя один запрос -
@Transaction
@Query("SELECT * FROM users_data")
fun getUserDataProfileList(): Flow<UserDataWithProfile>
Да, в отношениях «один к одному» между двумя таблицами в базе данных Room DB любое изменение в любой из таблиц вызовет поток, который получает связанные данные.
в этом случае, если мой API-интерфейс фонового сервера обновит таблицу «users_profile» последними изображениями пользователей, будет ли поток автоматически собирать новые данные, чтобы я мог обновить эти изображения в recyclerview?