Android MVC:向控制器发送消息
如这篇博客 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 中的控制器方法,例如 booleandispatchKeyEvent(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);
有什么优势?
我没有看到任何优点,对我来说,他甚至似乎打破了封装并不必要地暴露了这个类的内部结构。
编辑: 好吧,更简单的事情。你们采用什么方法将消息从视图发送到控制器?
As shown in this blog Mind The Robot, the author suggests the controller gets it's messages from the View through a handler like so:
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);
Because of the asynchronous of the sendMessage method and handler, I find this approach to be problematic in Android. If I'm to make a true controller, I need to delegate to the controller methods in the Activity like boolean dispatchKeyEvent(KeyEvent event). However, because handler is asynchronous I don't know if the KeyEvent was actually handled and can not return an appropriate value.
Instead I have chosen to pass my events from the View with just calling a method on the controller like
boolean sendMessage(int what);
boolean sendMessage(int what, Object data);
This way I can get an appropriate return value immediately from my controller and if the controller needs to handle these asynchronously it can transparently and I can still get a response back that the message will be handled either now or in the future.
My Question:
What advantage at all does the approach from MindTheRobot using
controller.getHandler.sendEmptyMessage(Controller.HANDLE_UPDATE);
have over something like
controller.sendMessage(Controller.HANDLE_UPDATE);
?
I don't see any advantages and to me it even seems like he is breaking encapsulation and exposing the internals of this class needlessly.
EDIT:
Okay, something easier. What approach do you guys take to sending messages from your Views to your Controllers?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
MVC 架构中的视图和模型都应该编写为独立的、独立的组件。另一方面,控制器可能(并且在实践中通常)暴露于视图和模型的实现细节。
这意味着,如果您在 MVC 视图中获得了对 MVC 控制器的引用(我知道您确实这样做了),那么您的 MVC 就有些“损坏”了。 MVC 视图不应该了解与其绑定的控制器。
解决此问题的一种方法是使用 观察者设计模式 - 让您的控制器实现预定义的接口,而视图允许观察者注册通知。
不过,我觉得这个方法有点麻烦,所以我寻找替代方法。 GreenRobot 的 EventBus 在这种情况下简直就是一个宝藏 - 易于使用、快速且轻便。尝试一下。
我还创建了 MVP 教程/模板应用程序,它演示了您可以使用的方法之一。它使用前面提到的 EventBus 进行组件之间的通信。源代码在这里:https://github.com/techyourchance/android_mvc_template
Both views and models in MVC architecture should be written as standalone, independent components. The controller, on the other hand, might be (and, in practice, usually is) exposed to implementation details of both the view and the model.
This means that if you got a reference to the MVC controller in your MVC view (and I understand that you do) - your MVC is somewhat "broken". MVC view should know nothing about the controller which will be tied to it.
One way to go about this is to use Observer Design Pattern - make your controllers implement a predefined interface, while the views allow for observers to register for notifications.
However, I think that this method is a bit cumbersome, therefore I searched for an alternative. GreenRobot's EventBus is simply a treasure in this context - easy to use, fast and light. Give it a try.
I also created MVP tutorial/template application which demonstrate one of the approaches you could use. It uses the aforementioned EventBus for communication between components. The source code is here: https://github.com/techyourchance/android_mvc_template