在 Google 的关于advanced-coroutines-codelabConflatedBroadcastChannel
示例的官方代码实验室中,他们曾经观察变量/对象的变化。
我在我的一个副项目中使用了相同的技术,当恢复监听活动时,有时会ConflatedBroadcastChannel
触发它的最近值,导致flatMapLatest
body 的执行没有任何变化。
我认为这是在系统收集垃圾时发生的,因为我可以通过System.gc()
从另一个活动调用来重现此问题。
这是代码
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
val tvCount = findViewById<TextView>(R.id.tv_count)
viewModel.count.observe(this, Observer {
tvCount.text = it
Toast.makeText(this, "Incremented", Toast.LENGTH_LONG).show();
})
findViewById<Button>(R.id.b_inc).setOnClickListener {
viewModel.increment()
}
findViewById<Button>(R.id.b_detail).setOnClickListener {
startActivity(Intent(this, DetailActivity::class.java))
}
}
}
主视图模型.kt
class MainViewModel : ViewModel() {
companion object {
val TAG = MainViewModel::class.java.simpleName
}
class IncrementRequest
private var tempCount = 0
private val requestChannel = ConflatedBroadcastChannel<IncrementRequest>()
val count = requestChannel
.asFlow()
.flatMapLatest {
tempCount++
Log.d(TAG, "Incrementing number to $tempCount")
flowOf("Number is $tempCount")
}
.asLiveData()
fun increment() {
requestChannel.offer(IncrementRequest())
}
}
详细活动.kt
class DetailActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail)
val button = findViewById<Button>(R.id.b_gc)
val timer = object : CountDownTimer(5000, 1000) {
override fun onFinish() {
button.isEnabled = true
button.text = "CALL SYSTEM.GC() AND CLOSE ACTIVITY"
}
override fun onTick(millisUntilFinished: Long) {
button.text = "${TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished)} second(s)"
}
}
button.setOnClickListener {
System.gc()
finish()
}
timer.start()
}
}
这是完整的源代码: CoroutinesFlowTest.zip
- 为什么会这样?
- 我错过了什么?