Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handler to Handler VERSUS Messenger to Messenger communication in Android

The question:

Is it "better" (= faster and less overhead) to use Handler to Handler communication compared to using Messenger to Messenger communication in Android?

The situation:

Android App that has a bunch of activities and one service running (started service). Within the service a few threads are running next to the main thread of the service. Application is started, first activity starts the service, service starts, first activity forwards to second activity, second activity binds to service,...

Handler to Handler:

...service hands out reference to service handler, second activity defines its own handler, second activity can now communicate to service directly using the service handler. To let the service handler know it has to reply to an activity handler, the msg.obj field within a Message object can be used to set the "reply-to" handler (= the handler within the activity). Now a two-way communication is sucessfully setup between activity and service.

Messenger to Messenger:

...service hands out reference to service messenger, second activity defines its own messenger, second activity can now communicate to service indirectly using the service messenger, which translates the message (Message object) into a Parcelable object, then re-translates the Parcelable object back into a new (but equal) Message object, which is handed over to the handler of the service. To let the service messenger know it has to reply to the activity messenger, the msg.replyTo field can be set with the messenger within the activity. Two-way communication sucessfully setup.

The "problem":

Why do I need Messenger to Messenger setup when I only need direct communication in my App that is within the boundaries of only one process? All threads within one process can easily communicate through the use of their Handlers (assuming these threads all have setup their own handlers correctly). I don't want messengers first flattening the Message objects shared between to two Handlers, that is just added overhead without any purpose besides "following the Android Service tutorial blindly".

Possible solution:

Start the service, bind once to it, let the service hand out a local binder object, set within the ServiceConnection implementation of onServiceConnected() the service handler within the activity, let the activity store it somewhere in a global memory space, switch to a third, forth, fifth activity and you never have to bind again in all the other activities, because all activities know their own handler (setup in each activity separate) and the can get the service handler from the global memory space. If the service needs to respond to the handler of the fourth activity, the fourth activity just adds its own handler (fourthHanlder) to the msg.obj field and the service knows whereto the reply message must be sent. That's it.

Besides that: the activity runs on the ui-thread/main-thread and the service runs also on the ui-thread/main-thread, so actually they are part of the same thread, only different handlers. Or is this incorrect thinking on my part?

This means the whole Messenger thing is only extra overhead for local (internal) communication between threads in the same process! It is not needed, unless the Android system figures out internally if the Messengers mutually communicate within the same process and bypass the flattening of the Messages and skip the translation into Parcelable objects, so that the Messengers actually communicate sortof directly between the Handlers themselves (without the user/programmer actually being aware of this. Well at least I am not aware of this if this is true what I am thinking right now).

I see that there are only three ways you can create asynchronous communication between activities and services by using:

  • Intents (can't send objects with an Intent!)
  • Messengers (are limited in possibilities compared to using Handlers directly, for example: you can't queue a message to the front of the queue)
  • Handlers (only possible when the threads to which the handlers belong are within the same process, otherwise you DO need Messengers)

I believe the handlers are the fastest way to communicate between threads, followed up by the messengers and last are intents. Is this TRUE???

Please share your insights and experiences on this matter, even when I am seeing this incorrectly :) Thank you.

like image 447
user504342 Avatar asked Jan 12 '23 01:01

user504342


1 Answers

I see that there are only three ways you can create asynchronous communication between activities and services

Nonsense.

Nowadays, I would use an event bus for service->activity communications (LocalBroadcastManager, Square's Otto, greenrobot's EventBus). No need to bind, no need for your own Handler, no need for your own Messenger, and greater flexibility.

Beyond that, if you are using binding, just create your own listener interface, no different than how you use an OnClickListener to listen to button clicks. The only change is that you would be raising the event (calling the method on the listener) in addition to receiving the event.

And, there's also ResultReceiver, though I do not see that used nearly so much.

like image 63
CommonsWare Avatar answered Apr 25 '23 02:04

CommonsWare