Cod*_*Lee 3 android android-lifecycle kotlin-flow
我正在尝试在 中显示用户信息DetailActivity。因此,我请求数据并从服务器获取用户的数据。但在本例中,返回类型是Flow<User>. 让我向您展示以下代码。
ServiceApi.kt
@GET("endpoint")
suspend fun getUser(@Query("id") id: Int): Response<User>
Run Code Online (Sandbox Code Playgroud)
存储库.kt
fun getUser(id: Int): Flow<User> = flow<User> {
val userResponse = api.getUser(id = id)
if (userResponse.isSuccessful) {
val user = userResponse.body()
emit(user)
}
}
.flowOn(Dispatchers.IO)
.catch { // send error }
Run Code Online (Sandbox Code Playgroud)
详细视图模型.kt
class DetailViewModel(
private val repository : Repository
) {
val uiState: StateFlow<User> = repository.getUser(id = 369).stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = User() // empty user
)
}
Run Code Online (Sandbox Code Playgroud)
详细活动.kt
class DetailActivity: AppCompatActivity() {
....
initObersevers() {
lifecycleScope.launch {
// i used the `flowWithLifecycle` because the data is just a single object.
viewModel.uiState.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).collect { state ->
// show data
}
}
}
...
}
Run Code Online (Sandbox Code Playgroud)
但是,突然间,我意识到这个过程是公正的an one-shot operation,并认为我可以使用suspend函数并User返回Repository.kt.
所以,我改变了Repository.kt。
存储库.kt(已更改)
suspend fun getUser(id: Int): User {
val userResponse = api.getUser(id = id)
return if(userResponse.isSuccessful) {
response.body()
} else {
User() // empty user
}
}
Run Code Online (Sandbox Code Playgroud)
在 中DetailViewModel,我想将 转换User为StateFlow<User>因为观察 fromDetailActivity并且我将像以前一样通过使用 来使用它flowWithLifecycle。
这个概念是......我认为这只是一个数据,我不需要Flow在存储库中使用。因为它不是像这样的几个项目List。
这种方式正确还是错误??
是的,这种一次性流没有任何意义——它只发射一次,仅此而已。
你有两种不同的方法。首先 - 在您的存储库中创建一个状态流,并在每次执行 GET 请求时发出任何值。该流程将暴露于用例和虚拟机级别。我想说这会导致更困难的错误处理(我不喜欢这种方式,但这些事情总是有争议的,哈哈),但它也有一些优点,比如缓存,你总是可以显示/获取以前的结果。
第二种方法是将您的请求保留为一个简单的挂起函数,该函数发送请求,将其结果返回到您的虚拟机(为了简单起见,这里跳过错误处理):
val userFlow: Flow<User>
get() = _userFlow
private val _userFlow = MutableStateFlow(User())
fun getUser() = launch(viewModelScope) {
_userFlow.value = repository.getUser()
}
Run Code Online (Sandbox Code Playgroud)
这种实现不会提供任何超出该虚拟机生命周期范围的缓存,但它很容易测试和使用。因此,并不是只有一种“最酷的方法”,而是一个问题,哪种方法更适合您的需求。
| 归档时间: |
|
| 查看次数: |
1654 次 |
| 最近记录: |