首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Livedata上多次调用postValue()只会得到最后一个调度。有什么解决办法吗?

在Livedata上多次调用postValue()只会得到最后一个调度。有什么解决办法吗?
EN

Stack Overflow用户
提问于 2021-03-20 17:19:05
回答 3查看 1.6K关注 0票数 3

正如文件中提到的Livedata#postValue(T)

如果在主线程执行posted任务之前多次调用此方法,则只分配最后一个值。

但是我确实需要在短时间内在Livedata上多次调用postValue()。我正在设计一个具有下载功能的应用程序。我在AndroidViewmodel中编写下载代码,并为每个asyns下载任务启动一个新线程。一旦每个任务完成,它就会将postValue()发送到Livedata,因此可能会有许多任务同时向相同的Livedata提交值,因此只有最后一次发布才能工作。

是否允许我同时多次对Livedata进行postValue(),并确保所有相关的观察者都对所有帖子作出反应?

--我的代码示例如下

在AndroidViewModel类中:

代码语言:javascript
运行
复制
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;
}

在活动中:

代码语言:javascript
运行
复制
    androidViewModel.bulkDownload(a_list_of_tasks)
    androidViewModel.getCompletedTask().observe(this, new Observer<DataHolder_Task>() {
        @Override
        public void onChanged(DataHolder_Task task) {
            doSomething(task)
        }
    });
EN

回答 3

Stack Overflow用户

发布于 2021-12-02 04:23:19

我通过子类MutableLiveData实现了这一点,添加了一个队列来缓冲大量活动数据,然后将一个地分派到主线程:

代码语言:javascript
运行
复制
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)
            }
        }
    }
}
票数 2
EN

Stack Overflow用户

发布于 2021-12-02 06:19:32

LiveData被设计为一个生命周期感知的可观察对象,它通知UI最新的状态。它不是事件流。

有什么解决办法吗?

试试Kotlin流

票数 1
EN

Stack Overflow用户

发布于 2022-06-09 05:48:22

您可以尝试使用.setValue() (或Kotlin的.value )代替.postValue()。为我工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66724421

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档