【问题标题】:Android MVC: Sending Messages to the ControllerAndroid MVC:向控制器发送消息
【发布时间】:2011-12-29 01:46:10
【问题描述】:

如本博客Mind The Robot 所示,作者建议控制器通过如下处理程序从视图获取消息:

inboxHandlerThread = new HandlerThread("Controller Inbox"); // note you can also set a priority here
inboxHandlerThread.start();

    // ... some code omitted ...

inboxHandler = new Handler(inboxHandlerThread.getLooper()) {
  @Override
  public void handleMessage(Message msg) {
    Controller.this.handleMessage(msg);
  }
};

// from the View
controller.getHandler.sendEmptyMessage(Controller.HANDLE_UPDATE);

由于 sendMessage 方法和处理程序的异步性,我发现这种方法在 Android 中存在问题。如果我要制作一个真正的控制器,我需要委托给 Activity 中的控制器方法,例如 boolean dispatchKeyEvent(KeyEvent event)。但是,由于处理程序是异步的,我不知道 KeyEvent 是否已实际处理并且无法返回适当的值。

相反,我选择从视图中传递我的事件,只需调用控制器上的方法,如

boolean sendMessage(int what);
boolean sendMessage(int what, Object data);

这样我可以立即从我的控制器获得一个适当的返回值,如果控制器需要异步处理这些,它可以透明地获得,我仍然可以得到一个响应,即现在或将来会处理该消息。

我的问题: MindTheRobot 使用的方法有什么优势

controller.getHandler.sendEmptyMessage(Controller.HANDLE_UPDATE);

有过类似的事情

controller.sendMessage(Controller.HANDLE_UPDATE);

?

我没有看到任何优势,在我看来,他甚至似乎在破坏封装并不必要地暴露这个类的内部。

编辑: 好吧,更简单的事情。你们采用什么方法将消息从视图发送到控制器?

【问题讨论】:

  • 对我来说这个问题也很有趣
  • 我写了一个博客系列来回答这些类型的问题:therealjoshua.com/blog

标签: android model-view-controller controller handler


【解决方案1】:

MVC 架构中的视图和模型都应编写为独立的、独立的组件。另一方面,控制器可能(并且实际上通常是)暴露于视图和模型的实现细节。

这意味着,如果您在 MVC 视图中获得了对 MVC 控制器的引用(我知道您这样做了)- 您的 MVC 有点“损坏”。 MVC 视图应该对绑定到它的控制器一无所知。

解决此问题的一种方法是使用Observer Design Pattern - 使您的控制器实现预定义的接口,而视图允许观察者注册通知。

但是,我认为这种方法有点麻烦,因此我寻找了一种替代方法。 GreenRobot 的EventBus 在这种情况下简直就是宝藏——易于使用、快速、轻便。试试看吧。

我还创建了 MVP 教程/模板应用程序,它演示了您可以使用的一种方法。它使用前面提到的 EventBus 进行组件之间的通信。源码在这里:https://github.com/techyourchance/android_mvc_template

【讨论】: