Разница между sendToTarget и sendMessage

При отправке сообщения между потоками, представлениями или действиями существует два, казалось бы, идентичных способа сделать это.

Первое, и для меня самое интуитивное, это obtain Message затем используйте Handler "s sendMessageметод:

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

Или вы можете obtain сообщение, предоставляющее Handler затем используйте Message "s sendToTarget метод:

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

Почему существуют эти два способа достижения одного и того же? Они ведут себя по-разному?

2 ответа

Решение

Если вы проверите код Message.java, например, здесь вы увидите

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


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

Другими словами, sendToTarget() будет использовать ранее указанный Handler и вызвать его sendMessage()

Если вы ищете obtain() метод вы увидите:

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();
}

Представленное объяснение также очень хорошее:

Вернуть новый экземпляр сообщения из глобального пула. Позволяет нам избежать выделения новых объектов во многих случаях.

Делать то же самое для obtain(Handler h):

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

    return m;
}

Вы можете подтвердить, что obtain(Handler h) на самом деле obtain() с добавлением задания цели Handler

То же, что и receive (), но устанавливает значение для целевого элемента в возвращаемом сообщении.

Есть несколько других перегрузок, просто проверьте Message.java и ищите "получить"

  • 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)
  • ...

Надеюсь, это поможет, ура!

Сообщение взято из внутреннего пула, поэтому сборка мусора не будет зависеть. Когда вы вызываете Message.obtain(Hanler), сообщение знает о получателе обработчика, а когда вы вызываете msg.sendToTarget(), оно доставляется этому обработчику. Вам следует рассмотреть возможность использования библиотеки rxJava для организации параллелизма вместо классов Android Message и Handler - это более удобно, и вы сможете делать с ней более сложные вещи.

Другие вопросы по тегам