Reputation: 11
I am building a chat application and updating my recycler with Coroutine Flow but the flow is running in loop and causing freeze and app crash.
Here is my collector :
dao!!.getSingleUsersMessages(roomId = roomId!!, alternateRoomId = roomId2!!).collect { messages ->
CoroutineScope(Dispatchers.Main).launch {
adapter.populate(messages)
if (adapter.itemCount > 0) {
Timber.tag("issueTracker_").d(messages.size.toString())
//binding.chattingRecycler.smoothScrollToPosition(0)
}
withContext(Dispatchers.IO) {
dao!!.updateRead(roomId!!)
dao!!.updateRead(roomId2!!)
}
}
//cancel()
}
My Dao query :
@Query("SELECT * FROM message_table WHERE roomId=:roomId OR roomId=:alternateRoomId ORDER BY time DESC LIMIT 250")
fun getSingleUsersMessages(roomId: String, alternateRoomId: String) : Flow<List<Message>>
Log:
2021-12-02 11:19:29.129 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.146 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.164 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.181 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.199 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.217 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.244 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.261 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.263 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.297 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.316 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.333 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.348 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.364 14569-14569/com.example.chatapplication D/issueTracker_: 3
2021-12-02 11:19:29.427 14569-14569/com.example.chatapplication D/issueTracker_: 3
Now If I am calling cancel()
it is cancelling the flow but not running again when adding new entry to the database.
How can I fix this Problem??
Upvotes: 1
Views: 1228
Reputation: 1127
I have found a solution to investing so much time.
Solution: Same Dao Object should be used when we insert details into the room database and get information from DB.
If you are using dagger hilt then
@Singleton annotation will work.
I hope this will solve your problem.
Upvotes: 0
Reputation: 1897
At the end of the collect
block you twice update message database. That causes flow to twice emit updated message list. It leads to infinite update-collect loop.
Apply distinctUntilChanged function to the flow to filter out of consecutive message lists that contains the same items in the same order. Also pass custom predicate as a parameter to define which messages should be considered the same.
For example, if you want to skip collecting message lists containing the same IDs collection:
val idEquality = { oldMessages: List<Message>, newMessages: List<Message> ->
oldMessages.map(Message::id) == newMessages.map(Message::id)
}
dao!!.getSingleUsersMessages(roomId = roomId!!, alternateRoomId = roomId2!!)
.distinctUntilChanged(idEquality)
.collect { messages ->
Upvotes: 2