小编Dev*_*urt的帖子

Kotlin 协程 - 返回 Flow 的挂起函数永远运行

我正在制作一个支持多个数据检索配置的网络存储库,因此我想将这些配置的逻辑分离为函数。

但是,我有一个配置,可以按指定的时间间隔连续获取数据。当我将这些值发送到原始流程时,一切都很好。但是,当我将逻辑放入另一个函数并通过它返回另一个流时,它不再关心其协程范围。即使范围取消后,它仍会继续获取数据。

TLDR:当使用 currentCoroutineContext 来控制循环的终止时,返回流的挂起函数将永远运行。

我在这里做错了什么?这是我的代码的简化版本:

调用 viewmodels 函数的片段基本上调用 getData()

 lifecycleScope.launch {
            viewModel.getLatestDataList()
        }
Run Code Online (Sandbox Code Playgroud)

存储库

suspend fun getData(config: MyConfig): Flow<List<Data>>
{
    return flow {

        when (config)
        {
            CONTINUOUS ->
            {
                //It worked fine when fetchContinuously was ingrained to here and emitted directly to the current flow
                //And now it keeps on running eternally
                fetchContinuously().collect { updatedList ->
                    emit(updatedList)
                }
            }
        }
    }
}


//Note logic of this function is greatly reduced to keep the focus on the problem
private …
Run Code Online (Sandbox Code Playgroud)

multithreading android kotlin kotlin-coroutines

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

Android - 运动布局语法错误:没有有效的 LayoutDescription

当我从 ConstraintLayout 切换到 MotionLayout 时出现以下错误。我试过重建项目但没有用。

错误

布局代码:

<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_death_motion_layout"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_gravity="center"
android:layout_marginHorizontal="16dp"
android:background="@drawable/black_gray_gradient"
android:visibility="visible"
app:layoutDescription="@xml/dialog_fragment_death_scene"
tools:context=".ui.DeathDialogFragment">


<TextView
    android:id="@+id/game_over_text_tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="16dp"
    android:layout_marginTop="32dp"
    android:layout_marginEnd="16dp"
    android:text="@string/game_over"
    android:textAppearance="@style/TextAppearance.AppCompat.Display1"
    android:textColor="@android:color/white"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.496"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:id="@+id/score_tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="24dp"
    android:text="666"
    android:textAppearance="@style/TextAppearance.AppCompat.Display3"
    android:textColor="@android:color/white"
    app:layout_constraintEnd_toEndOf="@+id/game_over_text_tv"
    app:layout_constraintStart_toStartOf="@+id/game_over_text_tv"
    app:layout_constraintTop_toBottomOf="@+id/game_over_text_tv" />
Run Code Online (Sandbox Code Playgroud)

</androidx.constraintlayout.motion.widget.MotionLayout>

android android-studio

4
推荐指数
1
解决办法
1656
查看次数

Kotlin - 永远不会收到 MutableStateFlow Emmision

当我在不同的片段中更改 GameData 的 isInFavorites 属性时,我可以看到在我的存储库的侦听器中收到了更改,但是当我导航回片段时,当我使用 MutableStateFlow 时,我的视图模型永远不会收到更新的值。

奇怪的是,当我将流更改为 MutableSharedFlow 时,突然间视图模型也开始获取更新的值。有谁知道为什么会发生这种情况?我需要在这里使用 MutableStateFlow 但它不起作用。

存储库:

private val gameDataListResultMutableFlow: MutableStateFlow<Result<List<GameData>>> = MutableStateFlow(Result.Loading)



    override suspend fun observeGameDataList(): Flow<Result<List<GameData>>>
        {
   

      CoroutineScope(Dispatchers.IO + coroutineContext).launch {
                localGameDataSource.observeGameDataList().collectLatest{
                     if(it is Result.Success)
                     {
                        Timber.d("local data change favorite value of item 0: ${it.data[0].isInFavorites}")
                     }
               
                    gameDataListResultMutableFlow.emit(it)
                }
            }
    }
Run Code Online (Sandbox Code Playgroud)

视图模型

private suspend fun observeGameListResult()
{

    gameRepository.observeGameDataList().collect{

        if(it is Result.Success)
            Timber.d("data change received in viewmodel value of item 0: ${it.data[0].isInFavorites}")

        gameListResultMutableLiveData.postValue(it)
    }
}


fun getGameListResultLiveData(): LiveData<Result<List<GameData>>>
{
    launch(coroutineContext) {
        observeGameListResult()
    } …
Run Code Online (Sandbox Code Playgroud)

java android kotlin kotlin-coroutines kotlin-flow

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