Handler 發(fā)送消息
android中使用handler發(fā)送異步消息刷新UI是最基本的知識(shí)點(diǎn),但如何優(yōu)雅發(fā)送一個(gè)Message消息似乎很多人都是copy一個(gè)handler.sendMessage(...)
handler消息演變
//版本1
Message message = new Message();
message.what = 0;
message.obj = "hello";
mHandler.sendMessage(message);
↓
//版本2
Message message = mHandler.obtainMessage();
message.what = 0;
message.obj = "hello";
mHandler.sendMessage(message);
↓
//版本3
mHandler.obtainMessage(0,"hello").sendToTarget();
區(qū)別
版本1->版本2的區(qū)別就是使用消息池復(fù)用消息不會(huì)重復(fù)創(chuàng)建Message對(duì)象,但版本2->版本3的區(qū)別是什么?網(wǎng)上很多文章說(shuō)了一大堆看的有點(diǎn)亂,我總結(jié)就一個(gè)句話更加優(yōu)雅了,非要說(shuō)出一個(gè)區(qū)別來(lái)就是sendToTarget()不能對(duì)new的Message(沒(méi)有target的Message)使用。
口說(shuō)無(wú)憑上源碼
先看Message類的obtain()這個(gè)方法
/**
* Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>,
* <em>arg1</em>, and <em>arg2</em> members.
*
* @param h The <em>target</em> value to set.
* @param what The <em>what</em> value to set.
* @param arg1 The <em>arg1</em> value to set.
* @param arg2 The <em>arg2</em> value to set.
* @return A Message object from the global pool.
*/
public static Message obtain(Handler h, int what, int arg1, int arg2) {
Message m = obtain();
m.target = h;
m.what = what;
m.arg1 = arg1;
m.arg2 = arg2;
return m;
}
target其實(shí)就是handler對(duì)象,再看一下Handler.obtainMessage()方法
/**
*
* Same as {@link #obtainMessage()}, except that it also sets the what and obj members
* of the returned Message.
*
* @param what Value to assign to the returned Message.what field.
* @param obj Value to assign to the returned Message.obj field.
* @return A Message from the global message pool.
*/
public final Message obtainMessage(int what, Object obj)
{
return Message.obtain(this, what, obj);
}
最后看一下msg.sendToTarget();的實(shí)現(xiàn)
/**
* Sends this Message to the Handler specified by {@link #getTarget}.
* Throws a null pointer exception if this field has not been set.
*/
public void sendToTarget() {
target.sendMessage(this);
}
target.sendMessage(this);就相當(dāng)于mHandler.sendMessage(message);,所以版本2的mHandler.sendMessage(...);和版本3的mHandler.obtainMessage(...).sendToTarget();是等價(jià)的。但版本3一行代碼就可以實(shí)現(xiàn)著實(shí)優(yōu)雅。
總結(jié)
使用mHandler.obtainMessage(...).sendToTarget();來(lái)優(yōu)雅的發(fā)送消息
測(cè)試用例
@RunWith(AndroidJUnit4.class)
@LargeTest
public class HandlerAndroidTest {
@Test
public void testHandler() {
Message msg = mHandler.obtainMessage(0, "hello");
mHandler.sendMessage(msg);
msg.sendToTarget();
Message message = new Message();
message.what = 0;
message.obj = "new hello";
mHandler.sendMessage(message);
}
@Before
public void setUp() throws Exception {
mHandler = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.e(TAG, "callback handle message:" + msg);
return false;
}
}) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.e(TAG, "override handle message:" + msg);
}
};
}
final String TAG = "HandlerTest";
private Handler mHandler;
}