假设我有一个在我的应用程序中的2个位置使用的组件C. 例如,我有一个文件夹列表,显示在2个选项卡中.当用户在一个部分中重命名文件夹时,此更改也应反映在另一个部分中.
我正在考虑使用EventBus,并使文件夹组件触发EventBus事件,比如FolderChangedEvent.此事件将被第二个文件夹组件拦截,该组件将自动更新其文件夹列表.
问题是,如果我想在某个地方在第3个地方使用这个文件夹组件,这个地方也会更新文件夹列表.这可能不是应用程序的期望行为.
通常,我会使Folder组件有一个自己的addFolderChangedHandler(...)方法,但由于这个组件非常复杂并且有子组件,这可能会创建意大利面条类型的代码.但是,我不认为这个组件应该包含任何特定于应用程序的逻辑,并且直接在应用程序的EventBus中抛出事件,这对于它来说太高级了.
这种情况的最佳做法是什么?如何有效地使用EventBus?
所以,我的应用程序从/向我的MainActivity交换消息到/从后台服务,我使用EventBus来处理它.我正在注册这两个组件
EventBus.getDefault().register(this);
Run Code Online (Sandbox Code Playgroud)
在他们的onCreates.我正在发送/接收一个活动:
EventBus.getDefault().post(new MyMessagePojo("message"));
Run Code Online (Sandbox Code Playgroud)
和
public void onEvent(MyMessagePojo event) { ... }
Run Code Online (Sandbox Code Playgroud)
当我将项目从AndroidStudio运行到我的测试手机时,一切正常.但是,当我生成签名的APK时,我安装了应用程序并遇到以下异常崩溃:
Subscriber class my.package.MainActivity has no public methods called onEvent
Run Code Online (Sandbox Code Playgroud)
它显然有的地方.我尝试将其更改onEvent为onEventMainThread我的MainActivity,但没有成功.这是非常令人沮丧的,因为我即将发布应用程序,现在我无法解决这个问题.
有任何想法吗?
我应该在应用程序类中注册和取消注册事件总线吗?如果是,那么我应该在哪里注册和注销?
一旦在应用程序类中完成了事件总线的注册,那么我是否需要在订阅者类中注册事件总线?
如果我将一些方法作为订阅者方法放在 Application 类中,会出现什么问题吗?
我开始学习反应流,因为我很好奇使用RxJava作为更传统事件总线的替代品的新趋势. 这篇博文是对其完成方式的典型描述.如果我理解正确,RxJava 1.x并不是Reactive Streams的严格实现,但它非常相似.2.0版包含一些符合要求的类,或至少通过TCK,因此该代码的更新版本可能看起来有点不同.
public class UserLocationModel {
private PublishSubject<LatLng> subject = PublishSubject.create();
public void setLocation(LatLng latLng) {
subject.onNext(latLng);
}
public Observable<LatLng> getUserLocation() {
return subject;
}
}
Run Code Online (Sandbox Code Playgroud)
在Reactive Streams术语中,我认为subject是a Processor,它既是a Publisher又是a Subscriber.
问题是,呼吁onNext在Subscriber未订购任何东西,似乎违反了无流规范,特别是排除1.9.
这仅仅是一个实现细节吗? 我是否正确地认为您通常不能依赖此协议来实现兼容的Reactive Streams实施?
假设以下场景包含A,B类和一个事件总线实例(可以是Guava事件总线,由Google或Otto事件总线,由Squ.re提供)
class A{
@Subscribe
public void onSomething(B event){
//do something
}
}
A a = new A();
eventBus.subscribe(a);
eventBus.post(new B());
// onSomething is called, everything ok
a = null;
eventBus.post(new B());
// onSomething is called again
Run Code Online (Sandbox Code Playgroud)
现在,如果我运行它(仅用Otto测试)onSomething被调用2次.
¿事件总线是否会引用' a'直到取消注册?
更重要的是
¿如果由于某种原因我无法确定' a'将为null 的那一刻,那么事件总线将永远保持对该对象的无用引用(内存泄漏)?
我在我的Android应用程序中使用EventBus.在我的mainActivity中,我有这个处理程序方法,它将实时数据发送到EventBus,如下所示:
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case TGDevice.MSG_STATE_CHANGE:
EventBus.getDefault().postSticky(msg.arg1);
...
Run Code Online (Sandbox Code Playgroud)
我正在使用Fragments类,我需要从处理程序接收消息.
我在onCreateView方法中注册了Fragment类,如下所示:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_data_log, container, false);
EventBus.getDefault().register(this);
tv = (TextView) view.findViewById(R.id.tv);
}
public void onEvent(Message message){
tv.setText("Signal" + message);
}
Run Code Online (Sandbox Code Playgroud)
我有onEvent方法,假设在有事件时被调用.不幸的是,这种方法从未被调用.我认为这可能是被覆盖的方法,但似乎并非如此.
从EventBus中读取消息需要做什么?
此外,在调试模式下,我在哪里可以看到正在创建的线程数?(我正在使用Android Studio)
我正在使用GreenRobot的EventBus 3.0版.还有一个关于文档的部分说我们可以发布粘性事件,并接收我们必须订阅的事件,如下所示:
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent event) {
// Do something with the message.
// Is the event removed from the bus on this method?
}
Run Code Online (Sandbox Code Playgroud)
所以,我的问题是:一旦订阅者收到粘性事件,它们是否会自动从总线中删除,还是我必须手动删除它们?
注意:我知道我可以使用以下行在我的代码的任何其他位置手动删除它们:
EventBus.getDefault().removeStickyEvent(stickyEvent);
Run Code Online (Sandbox Code Playgroud)
但我想知道我是否真的需要在订阅者方法中这样做.
我正在尝试从前端到 vertx 后端建立 sock.js 连接。
我最初的尝试是这样的:
let token = '<the token>';
let data = {'Authorization' : 'Bearer ' + token};
let eb = new EventBus("http://localhost:8080/eventbus");
eb.onopen = function () {
eb.registerHandler('notifications', data, (err, msg) => {
// handle the response
});
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为我需要发送有关 EventBus 创建的身份验证数据,即使官方 sock.js 文档指出这不受支持。显然现在发送new EventBus("http://localhost:9090/eventbus", data)也不起作用。
https://github.com/sockjs/sockjs-node#authorisation
我的后端处理程序:
final BridgeOptions bridgeOptions = new BridgeOptions()
.addOutboundPermitted(new PermittedOptions().setAddress("notifications"))
final SockJSHandler sockJSHandler = SockJSHandler.create(vertx).bridge(bridgeOptions, event -> {
event.complete(true);
});
router.route("/eventbus/*").handler(ctx -> {
String token = ctx.request().getHeader("Authorization"); // null …Run Code Online (Sandbox Code Playgroud) import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
public class Test {
public static class Processing { }
public static class ProcessingResults { }
public static class ProcessingFinished { }
public static EventBus bus = new EventBus();
@Subscribe
public void receiveStartRequest(Processing evt) {
System.out.println("Got processing request - starting processing");
}
@Subscribe
public void processingStarted(Processing evt) {
System.out.println("Processing has started");
}
@Subscribe
public void resultsReceived(ProcessingResults evt) {
System.out.println("got results");
}
@Subscribe
public void processingComplete(ProcessingFinished evt) {
System.out.println("Processing has completed");
}
public static void main(String[] args) …Run Code Online (Sandbox Code Playgroud) 有什么方法可以解决容器中的依赖关系(实际上是在嵌套的 LifetimeScope 中注册的,而不是在容器中注册的)?
实际执行说明:
我有包含当前用户的基本信息的ApplicationContext类(在其构造函数中注入)。IServiceProvider它首先解析IHttpContextAccessorfrom serviceProvider,然后从 中提取用户信息httpContextAccessor.HttpContext。ApplicationContext类被注入到所有存储库/服务中。
但是,在一些静态类中,我正在ApplicationContext从静态 IoC 类(包装在其中的 autofac 容器)解析类。我认为这是唯一的解决方案,因为我无法注入静态构造函数。
我正在实现事件总线,我为其创建了EventBusContext从事件数据接收用户信息的类。
ApplicationContext仅当它获取为 null 时(这意味着此执行不是从 Http Request 开始) ,类才会尝试解析并EventBusContext从中IServiceProvider提取用户信息。HttpContext
一旦EventBus类从 RabbitMQ 接收到事件,它就会创建EventBusConext类,将用户信息添加到其中,并将其动态注册到新创建的嵌套中LifetimeScope,然后解析该类EventHandler并调用 Handle 方法(通过反射)。
一切都很完美! 仅当使用任何从静态类EventHandler解析类的类时才会出现此问题,因为静态类在内部尝试从 autofac 容器(包装在其中)解析,但未能成功。ApplicationContextIoCIoCEventBusContext