LondonRob
LondonRob

Reputation: 78863

Difference between sendToTarget and sendMessage

When sending a message between Threads, Views or Activities, there are two seemingly identical ways of doing it.

The first, and to me the most intuitive, is to obtain a Message, then use the Handler's sendMessage method:

Message msgNextLevel = Message.obtain();
msgNextLevel.what = m.what;
mParentHandler.sendMessage(msgNextLevel);

Or, you can obtain the message providing the Handler, then use the Message's sendToTarget method:

Message msg = Message.obtain(parentHandler);
msg.what = 'foo';
msg.sendToTarget();

Why do these two ways of achieving the same thing exist? Do they behave differently?

Upvotes: 8

Views: 7491

Answers (2)

HenriqueMS
HenriqueMS

Reputation: 3974

If you check Message.java code for example from here you will see

//Sends this Message to the Handler specified by getTarget().


public void sendToTarget() {
    target.sendMessage(this);
}

In other words, sendToTarget() will use a previously specified Handler and invoke its sendMessage()

If you look for the obtain() method you will see:

public static Message obtain() {
    synchronized (sPoolSync) {
        if (sPool != null) {
            Message m = sPool;
            sPool = m.next;
            m.next = null;
            m.flags = 0; // clear in-use flag
            sPoolSize--;
            return m;
        }
    }
    return new Message();
}

The explanation provided is also very good:

Return a new Message instance from the global pool. Allows us to avoid allocating new objects in many cases.

Doing the same for obtain(Handler h):

    public static Message obtain(Handler h) {
    Message m = obtain();
    m.target = h;

    return m;
}

You can confirm that obtain(Handler h) really is obtain() with the addition of setting the target Handler

Same as obtain(), but sets the value for the target member on the Message returned.

There are several other overloads , just check Message.java and search for "obtain"

  • obtain(Message orig)
  • obtain(Handler h, Runnable callback)
  • obtain(Handler h, int what)
  • obtain(Handler h, int what, Object obj)
  • obtain(Handler h, int what, int arg1, int arg2)
  • obtain(Handler h, int what, int arg1, int arg2, Object obj)
  • ...

Hope this helps, cheers!

Upvotes: 7

Alex Shutov
Alex Shutov

Reputation: 3282

Message is taken from internal pool so there will not be garbage collection overhead. When you call Message.obtain(Hanler), message knows about handler recipient and when you call msg.sendToTarget(), it is delivered to that handler. You should consider using rxJava library for organizing concurrency instead of Android's Message and Handler classes - it is more convenient and you'll be able to do mo comlex things with it.

Upvotes: 0

Related Questions