Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 为什么每个活动都要更新原始实时数据而不是最近的实时数据?_Android_Kotlin_Android Livedata_Android Mvvm_Android Livedata Transformations - Fatal编程技术网

Android 为什么每个活动都要更新原始实时数据而不是最近的实时数据?

Android 为什么每个活动都要更新原始实时数据而不是最近的实时数据?,android,kotlin,android-livedata,android-mvvm,android-livedata-transformations,Android,Kotlin,Android Livedata,Android Mvvm,Android Livedata Transformations,会议视图模型 fun observeAttendeesJoined(): LiveData<Array<AttendeeInfo>>? { return Repository.getAttendeesJoined() } fun onAttendeesJoined(attendeeInfo: Array<AttendeeInfo>) { Timber.d(" :$LOG_APP_NAME: MeetingVi

会议视图模型

fun observeAttendeesJoined(): LiveData<Array<AttendeeInfo>>? {
        return Repository.getAttendeesJoined()
    }
fun onAttendeesJoined(attendeeInfo: Array<AttendeeInfo>) {
        Timber.d(" :$LOG_APP_NAME: MeetingViewModel: :onAttendeesJoined: :size: ${attendeeInfo.size}")
        attendeeInfo.forEach {
            Timber.d(" :$LOG_APP_NAME: MeetingViewModel: :onAttendeesJoined: $attendeeInfo")
        }
        Repository.setAttendeesJoined(attendeeInfo)
    }
前台服务更改相应可变实时数据的值。 BaseActivity收到更新,我们将显示snackbar。 现在,当我们改变活动时,同样的结果会再次被触发,即使它不是由前台服务触发的

例如,如果我们在
活动A(扩展了基本活动)
中,前台服务将新与会者总数的值更改为5,我们将在
活动A中显示它,因为有5个用户加入了会议。用户在
活动A上花费了一些时间。一段时间后,当用户移动到
活动B(也扩展了BaseActivity)
,前台服务没有任何响应时,
活动B
接收到与活动A相同的最后更新,因此,活动B还显示了一个snackbar,其中有5个用户加入了会议,并且此模式在所有活动中都会继续

会议视图模型

fun observeAttendeesJoined(): LiveData<Array<AttendeeInfo>>? {
        return Repository.getAttendeesJoined()
    }
fun onAttendeesJoined(attendeeInfo: Array<AttendeeInfo>) {
        Timber.d(" :$LOG_APP_NAME: MeetingViewModel: :onAttendeesJoined: :size: ${attendeeInfo.size}")
        attendeeInfo.forEach {
            Timber.d(" :$LOG_APP_NAME: MeetingViewModel: :onAttendeesJoined: $attendeeInfo")
        }
        Repository.setAttendeesJoined(attendeeInfo)
    }
TendeesJoined(与会者信息:数组){
Timber.d(“:$LOG\u APP\u NAME:MeetingViewModel::onAttendeesJoined::size:${attendeinfo.size}”)
AttendeInfo.forEach{
Timber.d(“:$LOG\u APP\u NAME:MeetingViewModel::OnatendeesJoined:$AttendeInfo”)
}
存储库。SetAttendesJoined(attendeeInfo)
}
服务

 override fun onAttendeesJoined(attendeeInfo: Array<AttendeeInfo>) {
        attendeeInfo.forEach {
            Timber.d(" :$LOG_APP_NAME: ChimeService: :onAttendeesJoined: :id: ${it.attendeeId} :externalId: ${it.externalUserId} :attendeeInfo: $it :responseSize: ${attendeeInfo.size}")
        }
        meetingViewModel.onAttendeesJoined(attendeeInfo)
    }
覆盖TendeesJoined(与会者信息:数组){
AttendeInfo.forEach{
Timber.d(“:$LOG_APP_NAME:ChimeService::onAttendeesJoined::id:${it.attendeeId}:externalId:${it.externalUserId}:attendeeInfo:$it:responseSize:${attendeeInfo.size}”)
}
meetingViewModel.OnatendeesJoined(与会者信息)
}
每当前台服务更改相应的可变实时数据时,只有在新数据(5)发生更改时,新活动(在我们的示例中为活动B)才应得到更新,因为
meetingViewModel.observeateTendeesJoined()
仅返回新数据

如何在整个活动中接收唯一的更新

MeetingViewModel
的实例对于每个活动都是不同的,但是存储库数据是单一的(kotlin的对象声明),不是吗

我试图理解
Transformations.map
switchMap
,但不知道如何使用它来解决问题


感谢您的期待。

MutableLiveData
存储最后一个值,并在您在另一个
活动中观察它时发出它(因为您在singleton中存储
MutableLiveData
)。
也许您需要类似于
SingleLiveEvent
的东西。请参见

这就是LiveData的工作原理。它是为了获取最新的数据状态,而不是作为一个信息广播者。有各种各样的黑客试图让LiveData实现这一目的。您可以对SingleLiveEvent进行web搜索,以查找有关该主题的各种文章

你可以考虑用科特林的MutableSharedFlow来代替生活。它有一个
replay
参数,您可以将该参数设置为0(默认值),这样您的新活动就不会收到已经发生的更新。在我看来,这是一个比SingleLiveEvent更干净的解决方案

您的回购协议可以公开财产:

val attendeesJoined = MutableSharedFlow<Array<AttendeeInfo>>()

还有一个建议。数组应该很少使用。存储库公开只读列表更干净/更安全。数组是可变的和固定大小的,因此它们的用途非常有限,通常用于低级工作。

我建议您简化存储库。MutableLiveData是一个非常轻量级的对象,因此没有理由延迟加载它。即使您这样做了,您的函数也没有理由返回null值,因为当您返回它时,它不可能为null。我将完全删除该函数,只需公开一个公共属性
val AttendesJoined=MutableLiveData()
。我非常感谢您的建议。是的,在我将extraBufferCapacity和onBufferOverflow添加为
val AttendesJoined=MutableSharedFlow(extraBufferCapacity=1,onBufferOverflow=BufferOverflow.DROP_)之后,它就起作用了。
val attendeesJoined: SharedFlow<Array<AttendeeInfo>> = Repository.getAttendeesJoined()
private fun observeAttendeesJoined() {
    lifecycleScope.launchWhenResumed {
        meetingViewModel.attendeesJoined.collect {
            Timber.d(" :$LOG_APP_NAME: BaseActivity: :setObservers: onAttendeesJoined: $it")
            onAttendeesJoined(it)
        }
    }
}