Handler
的运行机制也是Android
主要的消息机制;
Handler
的主要作用是将一个任务切换到某个指定的线程中去执行;
Q:为什么Android
要提供这种功能呢?
A:Android
规定访问UI
只能在主线程中进行,但Android
又不建议在主线程中进行耗时操作。这时Handler
就排上用场啦,在子线程中进行拉取工作,用Handler
切换一下UI
访问的执行线程来处理UI
操作
好,我们先学会使用,再深入源码理解原理,
常规使用有两种: 一种post()
,一种sendMessage()
post
方法
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
// post方法 handler的创建
Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
/*post方法解决UI更新,直接在runnable里面完成更新操作,
这个任务会被添加到handler所在线程的消息队列中,即主线程的消息队列中*/
handler.post(new Runnable() {
@Override
public void run() {
String result = "更新UI";
Log.d(TAG, "接收到的消息是: " + result);
}
});
}
}).start();
}
}
sendMessage
方法
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
// sendMessage方法 handler的创建
private static Handler sHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
/*sendMessage方法更新UI的操作必须在handler的handleMessage回调中完成*/
switch (msg.what) {
case 1:
Log.d(TAG, "接收到的消息是: " + msg.obj);
break;
default:
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
/*sendMessage方法解决UI更新发送消息给handler(主线程中的handler)*/
Message msg = new Message();
msg.what = 1;
msg.obj = "更新UI";
sHandler.sendMessage(msg);
}
}).start();
}
}
两个方法都是在子线中获取到信息后在主线程中访问UI,分析下这两种方法的区别,上源码分析
post方法源码
/**
* Causes the Runnable r to be added to the message queue.
* 把任务r 添加到消息队列中
*/
public final boolean post(Runnable r) {
return sendMessageDelayed(getPostMessage(r), 0);//注意这里
}
public final boolean sendMessageDelayed(Message msg, long delayMillis) {
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
sendMessage方法源码
public final boolean sendMessage(Message msg) {
return sendMessageDelayed(msg, 0);//注意这里
}
可以看出这两个方法最终调用的都是同一个方法sendMessageDelayed()
,所以他们的本质都是一样的,只是用法的区别。post
方法把任务Runable r
包装成了message
。那sendMessageDelayed()
做了什么事,Handler究竟是怎样完成切换线程执行任务的呢,下篇继续深入
网友评论