使用Guava的EventBus,可以在创建总线的线程上运行用户代码吗?

 叶葳蕤1095190287 发布于 2023-02-08 13:26

使用Guava的EventBus,我希望能够从后台线程(称为"后台")发布到更新UI的特定线程(在本例中为线程"main").我认为以下方法可行,但这会调用后台线程中的订阅者代码:

package com.example;

import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import com.google.common.util.concurrent.MoreExecutors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class EventBusTester {

    private static final Logger log = LoggerFactory.getLogger(EventBusTester.class);

    public static void main(String... args) {
        new EventBusTester().run();
    }

    private void run() {
        log.info("Starting on thread {}.", Thread.currentThread().getName());

        final EventBus eventBus = new AsyncEventBus(MoreExecutors.sameThreadExecutor());
        eventBus.register(this);

        Thread background = new Thread(new Runnable() {
            @Override
            public void run() {
                long now = System.currentTimeMillis();
                eventBus.post(now);
                log.info("Posted {} to UI on thread {}.", now, Thread.currentThread().getName());
            }
        }, "background");
        background.start();
    }

    @Subscribe
    public void updateUi(Long timestamp) {
        log.info("Received {} on UI on thread {}.", timestamp, Thread.currentThread().getName());
    }
}

这打印出以下内容:

02:20:43.519 [main] INFO  com.example.EventBusTester - Starting on thread main.
02:20:43.680 [background] INFO  com.example.EventBusTester - Received 1387848043678 on UI on thread background.
02:20:43.680 [background] INFO  com.example.EventBusTester - Posted 1387848043678 to UI on thread background.

所以我的问题是:

    是否有可能做我想要的事情,例如我曾经错过的ExecutorService,或者编写自定义ExecutorService,或者

    我需要一些其他库来实现这一目标吗?例如Square的Otto(因为我也将在Android上使用它).

不过,我宁愿和纯净的番石榴呆在一起.

谢谢!

1 个回答
  • 如果使用EventBus实例,则该@Subscribe方法将在发布事件的同一线程上执行.

    如果您想要做一些不同的事情,那么请使用AsyncEventBus您可以提供的地方Executor来定义事件发布时的确切行为.

    例如,在Android上,要使每个@Subscribe方法都在主线程上运行,您可以执行以下操作:

    EventBus eventBus = new AsyncEventBus(new Executor() {
    
        private Handler mHandler;
    
        @Override
        public void execute(Runnable command) {
            if (mHandler == null) {
                mHandler = new Handler(Looper.getMainLooper());
            }
            mHandler.post(command);
        }
    });
    

    Looper.getMainLooper()返回应用程序的主尺蠖,其生活应用程序的主线程上.

    2023-02-08 13:27 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有