标签: kotlin-flow

Android kotlin 中 SharedFlow 的使用

嘿,我正在学习 kotlin 中的流程。我正在学习MutableStateFlowMutableSharedFlow。我尝试在现实世界的例子中学习MutableStateFlow。但我无法获得MutableSharedFlow示例,它更适合。我尝试了一些MutableStateFlow

例如,当我们从 api 获取数据时,我们可以使用 seal 类来进行相应的填充。

LoggedState.kt

sealed class LoggedState {
    data class OnSuccess(val data: List<XYZ>) : LoggedState()
    object OnEmpty : LoggedState()
    data class IsLoading(val isLoading: Boolean = true) : LoggedState()
    data class OnError(val message: String) : LoggedState()
} 
Run Code Online (Sandbox Code Playgroud)

设置ViewModel.kt

class SettingsViewModel : ViewModel() {

 var loggedMutableStateFlow = MutableStateFlow<LoggedState>(LoggedState.OnEmpty)

 fun fetchData(){
   val result = dataRepository.getLogged()
                result.handleResult(
                    onSuccess = { response ->
                        val data = response?.items
                        if (!data.isNullOrEmpty()) {
                            loggedMutableStateFlow.value …
Run Code Online (Sandbox Code Playgroud)

android kotlin kotlin-flow kotlin-stateflow kotlin-sharedflow

19
推荐指数
2
解决办法
1万
查看次数

launchWhenStarted 和 RepeatOnLifecycle(STARTED) 在收集流量方面的区别

\n

由于launchWhenStarted和repeatOnLifecycle(STARTED)提供完全不同的功能(launchWhenStarted暂停协程的执行,而repeatOnLifecycle取消并重新启动新的协程),如果新API的名称相似(例如,使用launchWhenever作为重新启动的API) ,开发人员可能会感到困惑,甚至在没有注意到的情况下互换使用它们。

\n
\n

来源

\n

什么时候使用哪个更简单的解释是什么?

\n

android kotlin kotlin-flow

19
推荐指数
2
解决办法
2万
查看次数

如何安全地(生命周期感知).collectAsState() StateFlow?

我正在尝试遵循官方指南,根据以下文章,使用 Compose 从 LiveData 迁移到 Flow/StateFlow:

\n

从 Android UI 收集流量的更安全方法

\n

从 LiveData 迁移到 Kotlin\xe2\x80\x99s 流程

\n

我尝试遵循第一篇文章末尾处的 Jetpack Compose 中的安全流集合中的建议。

\n
\n

在 Compose 中,副作用必须在受控环境中执行。\n 为此,请使用 LaunchedEffect 创建一个遵循可组合\xe2\x80\x99s 生命周期的协程。在其块中,如果您需要在主机生命周期处于某种状态时重新启动代码块,则可以调用\nsuspend Lifecycle.repeatOnLifecycle。

\n
\n

我设法以这种方式使用.flowWithLifecycle()来确保当应用程序转到后台时流不会发出:

\n
@Composable\nfun MyScreen() {\n\n    val lifecycleOwner = LocalLifecycleOwner.current\n\n    val someState = remember(viewModel.someFlow, lifecycleOwner) {\n        viewModel.someFlow\n            .flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED)\n            .stateIn(\n                scope = viewModel.viewModelScope,\n                started = SharingStarted.WhileSubscribed(5000),\n                initialValue = null\n            )\n    }.collectAsState()\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我发现这非常“样板”——一定有更好的东西。我想在 ViewModel 中使用 StateFlow,而不是在 @Composable 中转换为 StateFLow 的 Flow,并使用.repeatOnLifeCycle(),这样我就可以使用多个.collectAsState() …

android kotlin kotlin-coroutines android-jetpack-compose kotlin-flow

18
推荐指数
1
解决办法
1万
查看次数

单元测试新的 Kotlin 协程 StateFlow

最近作为 Kotlin 协程的一部分引入了该类StateFlow

我目前正在尝试它并在尝试对我的 ViewModel 进行单元测试时遇到问题。我想要实现的目标:测试我StateFlow是否在 ViewModel 中以正确的顺序接收所有状态值。

我的代码如下:

视图模型:

class WalletViewModel(private val getUserWallets: GetUersWallets) : ViewModel() {

val userWallet: StateFlow<State<UserWallets>> get() = _userWallets
private val _userWallets: MutableStateFlow<State<UserWallets>> =
    MutableStateFlow(State.Init)

fun getUserWallets() {
    viewModelScope.launch {
        getUserWallets.getUserWallets()
            .onStart { _userWallets.value = State.Loading }
            .collect { _userWallets.value = it }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的测试:

    @Test
fun `observe user wallets ok`() = runBlockingTest {
    Mockito.`when`(api.getAssetWallets()).thenReturn(TestUtils.getAssetsWalletResponseOk())
    Mockito.`when`(api.getFiatWallets()).thenReturn(TestUtils.getFiatWalletResponseOk())

    viewModel.getUserWallets()

    val res = arrayListOf<State<UserWallets>>()
    viewModel.userWallet.toList(res) //doesn't works

    Assertions.assertThat(viewModel.userWallet.value is State.Success).isTrue() //works, …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-viewmodel kotlin-coroutines kotlin-flow

17
推荐指数
2
解决办法
5356
查看次数

StateFlow 和 LiveData 有什么区别?

正如我在标题中提到的,我很好奇两者之间的一般差异。你能帮忙吗?我找不到具体的区别,因为互联网上有复杂的例子。

  1. 在性能方面有哪些差异?
  2. 在哪些场景下有优势?
  3. 将 StateFlow 与 Kotlin Flow 结合使用是有利的。但是在使用 LiveData 的项目中不切换到 StateFlow 会有什么风险呢?
  4. Google 是否会弃用 LiveData?:)

android kotlin android-livedata kotlin-flow kotlin-stateflow

17
推荐指数
1
解决办法
5253
查看次数

MutableSharedFlow - 重放和 extraBufferCapacity 之间的区别

MutableSharedFlow 有 3 个参数:replay、extraBufferCapacity 和 onBufferOverflow。replay 和 extraBufferCapacity 有什么区别?

该文档提到以下内容:

replay - 重播给新订阅者的值的数量(不能为负数,默认为零)。

extraBufferCapacity - 除了重放之外缓冲的值的数量。当还有剩余缓冲区空间时,emit 不会暂停(可选,不能为负数,默认为零)。

我不明白两者之间的区别以及何时需要 extraBufferCapacity > 0。 extraBufferCapacity 只是发射器的额外重播能力吗?

android kotlin kotlin-coroutines kotlin-flow kotlin-sharedflow

17
推荐指数
1
解决办法
6676
查看次数

Android中如何收集多个状态流

如何收集activity中的两个状态流?因为我只消耗了第一个流量。

例如,viewmodel内部是这样的:

class ExampleViewModel: ViewModel(){
    private val state = MutableStateFlow<HomeMainFragmentState>(HomeMainFragmentState.Init)
    private val products = MutableStateFlow<List<ProductEntity>>(mutableListOf())


    //to be consumed
    fun getState() : StateFlow<HomeMainFragmentState> = state
    fun getProducts() : StateFlow<List<ProductEntity>> = products
}
Run Code Online (Sandbox Code Playgroud)

然后在我看来是这样的:

private fun observe(){
      viewLifecycleOwner.lifecycleScope.launch {
      viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED){
            viewModel.getState().collect { state -> handleState(state) }
            viewModel.getProducts().collect{ products -> handleProducts(products) }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,只有第一个流被消耗,因为这种情况是“状态”产品从未被活动/片段消耗/执行。

如何解决这个问题?我还阅读了有关组合流程的信息,这是否意味着第二个流程取决于第一个流程的运行?

android kotlin android-livedata kotlin-flow

16
推荐指数
2
解决办法
1万
查看次数

使用 Retrofit + Kotlin Flow 处理错误的优雅方式

我最喜欢在 Android 上执行网络请求的方法(使用 Retrofit)。它看起来像这样:

// NetworkApi.kt

interface NetworkApi {
  @GET("users")
  suspend fun getUsers(): List<User>
}
Run Code Online (Sandbox Code Playgroud)

在我的 ViewModel 中:

// MyViewModel.kt

class MyViewModel(private val networkApi: NetworkApi): ViewModel() {
  val usersLiveData = flow {
    emit(networkApi.getUsers())
  }.asLiveData()
}
Run Code Online (Sandbox Code Playgroud)

最后,在我的活动/片段中:

//MyActivity.kt

class MyActivity: AppCompatActivity() {
  private viewModel: MyViewModel by viewModels()

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    viewModel.usersLiveData.observe(this) {
      // Update the UI here
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我喜欢这种方式的原因是因为它本身就可以与 Kotlin flow 配合使用,非常易于使用,并且有很多有用的操作(flatMap 等)。

但是,我不确定如何使用此方法优雅地处理网络错误。我能想到的一种方法是用作Response<T>网络 API 的返回类型,如下所示:

// NetworkApi.kt

interface NetworkApi {
  @GET("users")
  suspend …
Run Code Online (Sandbox Code Playgroud)

android kotlin retrofit kotlin-coroutines kotlin-flow

15
推荐指数
2
解决办法
2万
查看次数

Android Flow 与 StateFlow

我最近开始在 Android 中使用 Flows。我读到 Flows 很冷 StateFlows 很热,那么为什么我们应该更喜欢使用 StateFlows for Android 而不是 Flows 呢?使用 Flows 不是更好吗,因为当应用程序进入后台时它们会停止生产者?在 Android 开发中是否存在应该使用 Flows 而不是 Stateflow 的场景?

android kotlin-flow

15
推荐指数
3
解决办法
1万
查看次数

Kotlin - StateFlow 不向其收集器发出更新

我的应用程序中有一个 UserStateModel(数据类)类型的 StateFlow。

private val _userStateFlow: MutableStateFlow<UserStateModel?> = MutableStateFlow(UserStateModel())
val userStateFlow: StateFlow<UserStateModel?> = _userStateFlow
Run Code Online (Sandbox Code Playgroud)

这是用户状态模型

data class UserStateModel(
    val uid: String? = null,
    val username: String? = null,
    val profileImageUrl: String? = null,
    var isLoggedIn: Boolean = false,
    val isPremiumUser: Boolean = false,
    val posts: List<Post>? = listOf()
) 
Run Code Online (Sandbox Code Playgroud)

当我使用新的用户名更新 StateFlow 时,它会将更改发送给收集器并更新 UI。但是当我更改帖子内的属性时:列表?列表它不会发出更改。当我更改列表的大小时,它会更改,而当我更改索引 0 处的帖子的 name 属性时,它不会更改。如何检测 Data 类的子属性的更改?

现在我使用一个丑陋的解决方法,我补充道

val updateErrorWorkaround: Int = 0 
Run Code Online (Sandbox Code Playgroud)

到 UserStateModel 数据类并将其加一以便收集器收到通知

PS我正在使用 MVVM + Clean Architecture 和 Jeptack Compose

编辑 这是我的帖子模型:

data class …
Run Code Online (Sandbox Code Playgroud)

android kotlin kotlin-coroutines android-jetpack-compose kotlin-flow

14
推荐指数
1
解决办法
2万
查看次数