Handler 发送消息
android中使用handler发送异步消息刷新UI是最基本的知识点,但如何优雅发送一个Message消息似乎很多人都是copy一个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();
区别
版本1->版本2的区别就是使用消息池复用消息不会重复创建Message对象,但版本2->版本3的区别是什么?网上很多文章说了一大堆看的有点乱,我总结就一个句话更加优雅了
,非要说出一个区别来就是sendToTarget()
不能对new的Message(没有target的Message)使用。
口说无凭上源码
先看Message类的obtain()这个方法
/**
* Same as {@link #obtain()}, but sets the values of the target, what,
* arg1, and arg2 members.
*
* @param h The target value to set.
* @param what The what value to set.
* @param arg1 The arg1 value to set.
* @param arg2 The arg2 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
其实就是handler对象,再看一下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();
的实现
/**
* 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);
就相当于mHandler.sendMessage(message);
,所以版本2的mHandler.sendMessage(...);
和版本3的mHandler.obtainMessage(...).sendToTarget();
是等价的。但版本3一行代码就可以实现着实优雅。
总结
使用mHandler.obtainMessage(...).sendToTarget();
来优雅的发送消息
测试用例
@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;
}