Разница между 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 - это более удобно, и вы сможете делать с ней более сложные вещи.