3

@ContextSingleton用来标记依赖于上下文注入的单例。然而,从 RoboGuice 源代码和我自己的测试来看,似乎它在Application上下文和不同的活动上下文之间产生了差异。这是完全有道理的,只是当我将它与这样的事件管理工具一起使用时——至少对我来说——有问题:

@ContextSingleton
public class Service {
    @Inject
    private Context context;

    public void doSomething(@Observes MyEvent ev) {
        ...
    }
}

尽管该服务被定义为单例,但似乎在它第一次注入某处之前似乎没有创建它的实例,显然是通过延迟加载。因此,触发 aMyEvent不会使侦听器调用。我们当时认为我们可以在我们的应用程序中“手动”预先加载类,例如

RoboGuice.get(context).getInstance(Service.class);

并因此注册侦听器,但这仅在 Activity 中执行时才能正常工作,Activity 后来也注入EventManager来触发事件,但不是应用程序。

所以,在一个理想的世界里,我希望我可以告诉RoboGuice 它应该将单例绑定到哪个上下文,就像这样

@ContextSingleton(MyApplication.class)
public class Service {
    ...
}

但显然这是不可能的。

我错过了什么?

4

2 回答 2

2

我认为您错过了事件不会跨上下文传播并且是特定于上下文的 - 请参阅(旧但仍然有效的)事件文档中的“注意事项”部分。因此,即使您的单例在应用程序上下文中加载,它也无法知道每个活动的上下文中发生的事件。我认为他们这样做是有充分理由的,但是也许如果您将其子类化Application,则可以注入一个EventManager全局可访问的对象。

我还没有尝试过,所以我不确定它是否会起作用,无论如何,你必须将事件注入到不同的 EventManager 中,所以你最好为这个单例定义一个接口并工作那样的话,因为事件不会以你希望的方式传播。

于 2012-09-25T22:13:45.457 回答
2

@JRaymond 是对的。RoboGuice 事件侦听器的实例不能在多个上下文中侦听事件。

但这很容易解决。不要让你的单身人士直接听事件。每个活动都可以监听自己的事件,然后将单通置于给定状态:

public class MyActivity extends RoboActivity {
    @Inject 
    private InsideAppManager mInsideAppManager;

    public void onHandleResumeEvent( @Observes OnResumeEvent onStartEvent ) {
        mInsideAppManager.setInsideApp(true);
    }

    public void onHandlePauseEvent( @Observes OnPauseEvent onStopEvent ) {
        mInsideAppManager.setInsideApp(false);
    }
}

还有你的单身人士:

@Singleton
public class InsideAppManager {
    private boolean isInsideApp;

    public boolean isInsideApp() {
        return isInsideApp;
    }

    public void setInsideApp(boolean isInsideApp) {
        this.isInsideApp = isInsideApp;
    }
}
于 2013-08-30T11:30:43.377 回答