问题:
在Android中,使用Handler到处理程序的通信是否比使用Messenger到信使的通信更好(更快、开销更小)?
情况:
一个Android应用程序有许多活动和一个正在运行的服务(启动服务)。在服务内,除了服务的主线程外,还有一些线程在运行。 应用程序启动,第一个活动启动服务,服务启动,第一个活动转到第二个活动,第二个活动绑定到服务,...
从Handler到Handler:
...服务提供对服务处理程序的引用,第二个活动定义自己的处理程序,第二个活动现在可以使用服务处理程序直接与服务进行通信。要让服务处理程序知道它必须回复到一个活动处理程序,可以使用Message对象中的 msg.obj 字段设置“回复”处理程序(即活动内的处理程序)。现在成功建立了活动和服务之间的双向通信。
从信使到信使:
...服务分配了对服务信使的引用,第二个活动定义了自己的信使,第二个活动现在可以间接地使用服务信使与服务进行通信。服务信使将消息(Message对象)转换为Parcelable对象,然后重新将Parcelable对象转换回新的(但相等的)Message对象,并将其交给服务的处理程序。要让服务信使知道它必须回复活动信使,可以使用活动中的信使设置msg.replyTo字段。双向通信成功建立。
“问题”:
为什么需要“信使到信使”的设置,而我只需要在一个进程的边界内进行直接通信呢?在一个进程内部,所有线程都可以通过使用它们各自正确设置的处理程序轻松地进行通信。我不希望信使首先扁平化在两个处理程序之间共享的Message对象,这只会增加开销,除了“盲目遵循Android服务教程”外没有任何目的。
可能的解决方案:
启动服务,绑定一次,让服务提供一个本地绑定器对象,在ServiceConnection实现的onServiceConnected()中设置活动中的服务处理程序,让活动在全局内存空间中存储它,切换到第三、第四、第五个活动,您永远不必在所有其他活动中再次绑定,因为所有活动都知道它们自己的处理程序(在每个活动中单独设置),并且可以从全局内存空间获取服务处理程序。如果服务需要响应第四个活动的处理程序,则第四个活动只需将其自己的处理程序(fourthHanlder)添加到msg.obj字段中,服务就知道回复消息必须发送到哪里了。就是这样。此外:活动运行在UI线程/主线程上,服务也在UI线程/主线程上运行,因此实际上它们是同一个线程的一部分,只是不同的处理程序。或者这是我错误的想法吗?
这意味着整个 Messenger 只是同一进程中线程之间本地(内部)通信的额外开销!除非 Android 系统在内部确定 Messengers 是否相互通信在同一个进程中,并绕过消息的扁平化和跳过将其转换为 Parcelable 对象的翻译,以便 Messengers 实际上在处理程序之间直接通信(用户/程序员实际上并不知道)。我不知道这是否正确。
我发现只有三种方法可以使用:
- Intent(不能使用 Intent 发送对象!)
- Messenger(与直接使用 Handlers 相比,可能性受到限制,例如:无法将消息排队到队列的前面)
- Handlers(仅当处理程序所属的线程位于同一进程中时才可能,否则您需要使用 Messengers)
我相信 Handlers 是在线程之间通信的最快方法,其次是 Messengers,最后是 Intents。这是真的吗?
请分享您对此问题的见解和经验,即使我看错了 :) 谢谢。
startService()
发送命令。绑定是一种选择,但不是唯一的选择。 - CommonsWare