应用程序启动时,Android首先会开启一个主线程(UI线程),它管理着界面中的UI控件,进行事件分发,比如说button点击事件的响应。当程序中出现耗时操作,如果你将它放在主线程中,长时间未能完成,界面就会出现假死现象,系统会给出一个错误提示“强制关闭”。所以所有类似于网络请求的耗时操作都应该放在子线程中执行,并且子线程中不能涉及到UI更新。
子线程中不能涉及UI更新的原因是因为UI线程是线程不安全的,先说说线程安全的概念:线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问,直到该线程读取完,其他线程才可使用,不会出现数据不一致或者数据污染。对于Android更新界面,线程是并发执行的,而界面只有一个,这样一来,当你开启100个线程,都去设置同一个TextView的显示内容,每个显示内容都不一样,到底该听谁的?所以android在执行线程时,设置了检查机制,从而限制子线程更新UI。
事实上我们常常需要在线程中去执行一些UI操作,android提供了多种在子线程中更新UI的方法,例如:runOnUiThread(),handler post和handler sendMessage。这里我主要讲讲handler的用法。
(一)handler是什么?
handler是android给我们提供的用来更新UI的一套机制,消息处理机制,也可以用来发消息和处理消息。简单来说,handler是用来管理某个线程的消息队列。使用handler机制,所有的更新UI的操作,都是在主线程的消息队列中轮询去处理。google给我们提供这个机制,让我们不用去考虑多线程并发的问题。我们常用的都是UI线程的handler,当然也可以为子线程创建属于其自己的handler,但那并不常用。
(二)handler的原理
每一个handler会与一个线程进行绑定,这个线程必须带有MessageQueue(消息队列),当创建一个Handler时,会默认绑定到你创建handler的含有messageQueue的线程(UI线程)。
handler两个作用:1定时发送消息Message 2定时发送一个runnable对象。
一个handler只有一个队列,在调用Handler.post(Runnable runnable)方法时,会将runnable封装成一个Message;在队列执行时,会判断当前的Message里是否分装了Runnable,如果封装了,就直接执行Runnable,如果没有,将当前的Message传递给handleMessage(Message msg)处理。
(三)Handler与Looper、MessageQueue的关系?
Looper:内部包含了一个消息队列也就是MessageQueue,所有的Handler发送的消息都走向这个消息队列,Looper方法,就是一个死循环,不断的从MessageQueue取消息,如果有消息就处理消息,没有就阻塞MessageQueue。
而handler的内部会跟Looper进行关联,也就是说在handler的内部可以找到Looper,找到了Looper也就找到了MessageQueue,在Handler中发送消息,其实就是向MessageQueue中发送消息。
总而言之:handler负责发送消息,Looper负责接收消息,并直接把消息回传给handler自己(handler默认情况下会去当前线程拿到Looper)。
Android Handler机制
最新推荐文章于 2024-09-02 18:19:21 发布