android - 在 Livedata 上多次调用 postValue() 将导致仅调度最后一个。有没有其他解决方案?
问题描述
正如文件所说的那样 Livedata#postValue(T):
如果您在主线程执行发布的任务之前多次调用此方法,则只会分派最后一个值。
但我真的需要在短时间内在 Livedata 上多次调用 postValue() 。我正在设计一个具有下载功能的应用程序。我在 AndroidViewmodel 中编写下载代码,并为每个异步下载任务启动一个新线程。一旦每个任务完成,它就会 postValue() 到一个 Livedata,因此可能有许多任务同时向同一个 Livedata 发布 value,导致只有最后一个发布有效。
有没有办法让我同时向 Livedata 多次 postValue() 并确保所有相关的观察者对所有发布做出反应?
------我的代码示例如下---------------
在 AndroidViewModel 类中:
private MutableLiveData<DataHolder_Task> completedTask;
......
public void bulkDownload(List<DataHolder_Task> tasks){
new Thread(new Runnable() {
@Override
public void run() {
for(DataHolder_Task task:tasks)
{
//download() blocks untill task completed
download(task);
completedTask.postValue(task);
}
}
}).start();
}
public MutableLiveData<DataHolder_Task> getCompletedTask() {
if(completedTask==null){
completedTask=new MutableLiveData<>();
}
return completedTask;
}
在活动中:
androidViewModel.bulkDownload(a_list_of_tasks)
androidViewModel.getCompletedTask().observe(this, new Observer<DataHolder_Task>() {
@Override
public void onChanged(DataHolder_Task task) {
doSomething(task)
}
});
解决方案
我通过 subclass 实现了这一点MutableLiveData
,添加了一个队列来缓冲批量实时数据,然后一一分派到主线程:
import androidx.lifecycle.MutableLiveData
import java.util.*
class QueuedMutableLiveData<T> : MutableLiveData<T>() {
private val queue = LinkedList<T?>()
override fun setValue(value: T) {
super.setValue(value)
synchronized(queue) {
queue.pollFirst()
queue.peekFirst()?.run {
super.postValue(this)
}
}
}
override fun postValue(value: T?) {
synchronized(queue) {
queue.add(value)
if (queue.size == 1) {
super.postValue(value)
}
}
}
}
推荐阅读
- javascript - 在 'https://identitytoolkit.googleapis.com/v1/accounts:/signUp? 访问 XMLHttpRequest?来自 'http://localhost:8080' 的来源已被阻止
- php - Nextcloud 数据库迁移执行
- linux - 带有 ifort 的 tracebackqq() 导致分段错误
- flutter - Flutter 中带有 ListView 的 FAN 横幅
- docker - 使用 Wireguard 容器后面的端口绑定访问 Docker 容器
- python - 使用 OpenCV 和 Python 使用范围滑块(轨迹条)创建蒙版图像
- python - 如何在 Python 中用点覆盖水平条形图?
- bash - 复制(远程)某些文件夹
- c# - 如何在实体框架中的表中的两条记录之间建立关系
- html - 如何隐藏 form.errors 直到它处于活动状态