@Entity
data class Book(
@PrimaryKey
val ispn: String
val title: String,
val description: String,
val pages: Int
)
现在,让我们使用Flow和suspend函数创建一个DAO接口:
@Dao
interface FavoriteBooksDao {
@Query("SELECT * FROM book")
fun selectAll(): Flow<List<Book>> // No need to add suspend keyword, because it returns Flow, flows already uses coroutines.
@Insert
suspend fun insert(book: Book) // Simply, add suspend keyword to the function, to make it work with coroutines.
@Delete
suspend fun delete(book: Book) // Simply, add suspend keyword to the function, to make it work with coroutines.
}
class FavoriteBooksRepository @Inject constructor(
private val dao: FavoriteBooksDao
) {
fun getAll() = dao.selectAll() //Non-suspending function
suspend fun add(book: Book) = dao.insert(book) //suspending function
suspend fun remove(book: Book) = dao.delete(book) //suspending function
}
@HiltViewModel
class FavoriteBooksViewModel @Inject constructor(
private val repository: FavoriteBooksRepository
): ViewModel() {
// This is a mutable state flow that will be used internally in the viewmodel, empty list is given as initial value.
private val _favoriteBooks = MutableStateFlow(emptyList<Book>())
//Immutable state flow that you expose to your UI
val favoriteBooks = _favoriteBooks.asStateFlow()
init {
getFavoriteBooks()
}
/**
* This function is used to get all the books from the database, and update the value of favoriteBooks.
* 1. viewModelScope.launch is used to launch a coroutine within the viewModel lifecycle.
* 2. repository.getAll() is used to get all the books from the database.
* 3. flowOn(Dispatchers.IO) is used to change the dispatcher of the flow to IO, which is optimal for IO operations, and does not block the main thread.
* 4. collect is a suspending function used to collect the flow of books list, and assign the value to favoriteBooks.
* 5. each time the flow emits a new value, the collect function will be called with the list of books.
*/
fun getFavoriteBooks() {
viewModelScope.launch { //this: CoroutineScope
repository.getAll().flowOn(Dispatchers.IO).collect { books: List<Book> ->
_favoriteBooks.update { books }
}
}
}
/**
* This function is used to add a book to the database.
* 1. viewModelScope.launch is used to launch a coroutine within the viewModel lifecycle.
* 2. Dispatchers.IO is used to change the dispatcher of the coroutine to IO, which is optimal for IO operations, and does not block the main thread.
* 3. repository.add(book) is used to add the book to the database.
*/
fun addBook(book: Book) {
viewModelScope.launch(Dispatchers.IO) { //this: CoroutineScope
repository.add(book)
}
}
/**
* This function is used to remove a book from the database.
* 1. viewModelScope.launch is used to launch a coroutine within the viewModel lifecycle.
* 2. Dispatchers.IO is used to change the dispatcher of the coroutine to IO, which is optimal for IO operations, and does not block the main thread.
* 3. repository.remove(book) is used to remove the book from the database.
*/
fun removeBook(book: Book) {
viewModelScope.launch(Dispatchers.IO) { //this: CoroutineScope
repository.remove(book)
}
}
}
1条答案
按热度按时间ql3eal8s1#
好吧,你的问题很一般,但我会尽我所能回答,我想你至少有一个基本的协程,流和Hilt的知识,如果你没有,没有问题,至少尝试学习一些新的东西,我试图使它尽可能简单。
场景:
假设有一个简单的应用程序向用户显示书籍信息,用户可以将任何书籍添加到收藏夹中,从收藏夹中删除它们,并有一个屏幕来显示收藏的书籍。
我们有一个名为Book的简单实体类:
现在,让我们使用Flow和suspend函数创建一个DAO接口:
说明:
我们有三个功能:
selectAll()
:检索收藏的书籍列表。insert()
:插入一本新书。delete()
:删除一本书。要使插入和删除能够与协程一起工作,请为这两个函数添加
suspend
关键字。对于selectAll()
函数,它返回一个流,你可以把它看作是LiveData
的替代品,这可以让我们观察到当插入或删除一本新书时book
表上的变化,selectAll()
在插入/删除后会发出一个新的列表,允许你更新你的UI。注意selectAll()
不是一个suspend函数,因为它返回一个流,流已经使用了协程,所以我们不需要suspend
关键字。现在让我们创建仓库:
说明:
现在,您需要在存储库中添加DAO示例,使用Hilt注入它。
存储库中有3个函数将调用DAO函数,您将
add()
和remove()
作为挂起函数,因为您将insert()
和delete()
声明为DAO中的挂起函数,并且getAll()
在DAO中没有作为selectAll()
挂起,因为它返回了前面说过的流。最后,让我们实现ViewModel:
说明:
现在,您需要在viewModel中使用Repository示例,使用Hilt注入它。
我已经添加了文档,分别描述了所有的工作和功能,以尽可能清楚地说明,还注意到这些功能没有挂起,因为我们正在启动
viewModelScope
协程,这就足够了,不需要将这些功能标记为挂起。这就是在Room数据库、存储库和viewModel中将协程和流与应用程序集成的方式。您可以在流和协程上执行更高级的操作,以使您的应用程序更加健壮和高效。您可以根据应用程序的需求添加更多的操作和代码,我尝试用最简单的格式表示它。
最后,感谢您花时间阅读本文,希望对您有所帮助。