Kotlin MutableStateFlow.collect 正在删除值

cre*_*n90 9 android kotlin kotlin-coroutines

我有一个 Android 应用程序,在其中我尝试使用协程流来使用我自己的事件总线库替换现有的 Otto EventBus 。在设置 MutableStateFlow 的值然后在我的应用程序代码中收集时,我看到值被丢弃。我创建了一个更简单的项目来演示同样的问题。关于为什么值从 MutableStateFlow 中删除的任何想法?

项目的build.gradle

buildscript {
    ext.kotlin_version = "1.4.10"
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.0.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.gms:google-services:4.3.3'
        classpath 'com.google.firebase:firebase-crashlytics-gradle:2.3.0'
        classpath 'com.google.firebase:perf-plugin:1.3.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
Run Code Online (Sandbox Code Playgroud)

应用程序模块的build.gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'com.google.firebase.firebase-perf'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "com.cren90.sandbox"
        minSdkVersion 23
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.1'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7'

    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.fragment:fragment:1.2.5'
    implementation 'androidx.fragment:fragment-ktx:1.2.5'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
    implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.2.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0'
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
    implementation 'com.google.firebase:firebase-analytics:17.5.0'
    implementation 'com.google.firebase:firebase-crashlytics:17.2.1'
    implementation 'com.google.firebase:firebase-perf:19.0.8'
    implementation 'com.google.firebase:firebase-messaging:20.2.4'
    implementation 'com.jakewharton.timber:timber:4.7.1'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'androidx.navigation:navigation-runtime:2.3.0'
    implementation 'androidx.navigation:navigation-fragment:2.3.0'
    implementation 'androidx.navigation:navigation-ui:2.3.0'
    implementation 'androidx.navigation:navigation-runtime-ktx:2.3.0'
    implementation 'androidx.navigation:navigation-fragment-ktx:2.3.0'
    implementation 'androidx.navigation:navigation-ui-ktx:2.3.0'

    testImplementation 'junit:junit:4.13'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

}
Run Code Online (Sandbox Code Playgroud)

MainActivity.kt

package com.cren90.sandbox

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.navigation.findNavController
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import timber.log.Timber
import java.lang.RuntimeException

class MainActivity : AppCompatActivity() {

    val flow: MutableStateFlow<Int> = MutableStateFlow<Int>(0)

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



        CoroutineScope(Dispatchers.IO).launch {
            flow.collect {
                Timber.d("cren90 - $it")
            }
        }
    }

    override fun onStart() {
        super.onStart()
        (application as SandboxApplication).apply {
            startupTrace.putAttribute("APP_UUID", uuid)
            startupTrace.stop()
        }

    }

    override fun onResume() {
        super.onResume()


        for(i in 0..100) {
            flow.value = i
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望这会记录

2020-09-30 18:10:02.826 10533-10611/com.cren90.sandbox D/MainActivity$onCreate$1$invokeSuspend$$inlined$collect: cren90 - 0
2020-09-30 18:10:02.826 10533-10611/com.cren90.sandbox D/MainActivity$onCreate$1$invokeSuspend$$inlined$collect: cren90 - 1
2020-09-30 18:10:02.826 10533-10611/com.cren90.sandbox D/MainActivity$onCreate$1$invokeSuspend$$inlined$collect: cren90 - 2
...
2020-09-30 18:10:02.826 10533-10611/com.cren90.sandbox D/MainActivity$onCreate$1$invokeSuspend$$inlined$collect: cren90 - 98
2020-09-30 18:10:02.826 10533-10611/com.cren90.sandbox D/MainActivity$onCreate$1$invokeSuspend$$inlined$collect: cren90 - 99
2020-09-30 18:10:02.826 10533-10611/com.cren90.sandbox D/MainActivity$onCreate$1$invokeSuspend$$inlined$collect: cren90 - 100
Run Code Online (Sandbox Code Playgroud)

但它记录了

2020-09-30 18:10:02.826 10533-10611/com.cren90.sandbox D/MainActivity$onCreate$1$invokeSuspend$$inlined$collect: cren90 - 0
//Maybe 1 or 2 other random values in the 0-100 range
2020-09-30 18:10:02.826 10533-10611/com.cren90.sandbox D/MainActivity$onCreate$1$invokeSuspend$$inlined$collect: cren90 - 100
Run Code Online (Sandbox Code Playgroud)

Gle*_*val 17

StateFlow官方文档指出:

可变状态流的值可以通过设置其 value 属性来更新。对值的更新总是会被混淆。因此,慢速收集器会跳过快速更新,但始终收集最近发出的值。

您可以在这里找到 StateFlow 官方文档。