Android Handler机制
首先来明白两个概念
1.主线程(UI线程)
当一个程序第一次启动时,Android会同时启动一个主线程。 主线程为管理界面中的UI控件,进行 “**事件分发 **” ; 比如说, 你要是点击一个 Button, Android会分发事件到Button上进行处理,来响应你的操作。所以主线程通常又被叫做 UI线程。
2.Android的消息传递机制
当我们需要一个耗时的操作,例如: 联网读取数据,或者读取本地较大的一个文件的时候,如果你放在主线程中的话,界面会出现假死现象,如果5秒钟还没有完成的话,会收到Android系统的一个错误提示 "强制关闭"。所以我们不能把这些操作放在主线程中,
这个时候我们需要把这些耗时的操作,放在一个子线程中 , 因为子线程涉及到UI更新,“* Android主线程是线程不安全的 ”,也就是说“*Android只允许UI线程(即主线程)修改更新UI组件 **”,子线程中操作是危险的。所以就有了Handler的出现,来解决这个复杂的问题。
运行的一个过程:
由于Handler运行在主线程中(UI线程中),它与子线程可以通过Message对象来传递 数据,这个时候,Handler就承担着接受子线程传过来的(子线程用sendMessage()方法传递过来的Message对象,(里面包含数据) , 把这些消息放入主线程队列中,配合主线程进行更新UI。
总结Handler类的主要两个作用
在新启动的线程中发送消息。
在主线程中获取,处理消息
接下来记住这几个类的作用
接下来记住这几个类的作用,为后续做准备;
- Looper :每个线程只有一个Looper , 它负责管理MessageQueue(消息队列),会不断从MessageQueue中取出消息,并将消息分给对应的Handler处理。
- MessageQueue:有Looper负责管理。它采用先进先出的方式管理Message。
- Handler:它能把消息发送给Looper管理的MessageQueue,并负责Looper分给它的消息
Handler的基本使用
1.Handler中分发消息的一些方法
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.
2.来个示例,新建一个线程来给主线程发送消息
public class MainActivity extends Activity{
private static final int send_msg_code = 0x101;
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
int what = msg.what;
if(what == send_msg_code){
Toast.makeText(MainActivity.this,"成功",Toast.LENGTH_SHORT).show();
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
new Thread(new Runnable(){
handler.sendEmptyMessage(send_msg_code);
}).start();
}
}
上面示例代码图解(图片来自网上)
0_1305267783GgXG.jpg(下面这段话配合上面图解,可以好好的细细品尝一番)
从这个图中我们很清楚可以看到调用sendEmptyMessage后,会把 Message对象放入一个MessageQueue队列,该队列属于某个Looper对象,每个Looper对象通过ThreadLocal.set(new Looper())跟一个Thread绑定了,Looper对象所属的线程在Looper.Loop方法中循环执行从MessageQueue队列读取Message对象,并把Message对象交由Handler处理,调用Handler的dispatchMessage方法。
总结:
看完了以上内容,那么能说出Handler是如何接受Message对象并处理的了吗?
(我们起码要记住下面这几点,上面的内容也是一直在强调着几点)
1.在子线程中调用Handler.sendMessage(msg);
2.将Message对象放入一个MessageQueue队列,该队列属于某个Looper对象
3.Looper对象所属的线程在Looper.Loop方法中循环执行从MessageQueue队列读取 Message对象
4. 把Message对象交由Handler处理
最后:
最后,最后是什么呢?
这里我们只是对Handler进行简单的说明,帮助理解,一些具体的使用,跟一些它的方法;最后,最后我们当然就是遵从最权威的官方文档 啦。
下面贴出官方文档链接方便查看
https://developer.android.com/reference/android/os/Handler.html
(官网可能要“墙”,没墙的可以点击下面另一个链接,也能查看文档,帮助我们更好的理解和使用这个类)
http://android-doc.com/reference/android/os/Handler.html