Handler的两个主要作用:
1.调度messages和runnables在时间上的执行
2.把一个动作放到一个线程上执行
根本目的就是解决多线程并发的问题
下面我们来写一个例子来更新UI
新建布局文件activity_handler.xml
对应的我们修改HandlerActivity.java的代码,使它实现一秒后更新文本的功能
运行代码,可以看到程序报错‘只有创建视图层次结构的原始线程可以更改其视图’
我们修改HandlerActivity.java的代码
运行程序,文本被成功的更改了
接下来我们利用Handler来做一个图片轮播
布局文件的代码
编写java代码
这样一个轮播就做好,运行程序
方法 |
解释 |
post(Runnable) |
将Runnable添加到消息队列,runnable将在handler所关联的线程上运行。如果Runnable成功放入到队列,则返回true,否则返回false,通常是因为looper正在退出处理消息队列。 |
postAtTime(Runnable,long) |
将Runnable添加到消息队列,并在指定的时间运行 |
postDelayed(Runnable,long) |
将Runnable添加到消息队列,并在指定时间后运行 |
sendEmptyMessage(int what) |
发送仅包含what值的消息 |
sendMessage(Message) |
将消息添加到消息队列挂起消息队列末尾,它将在handleMessage(Message)中被接收 |
sendMessageAtTime(Message,long) |
将消息在特定时间添加到消息队列挂起消息末尾 |
sendMessageDelayed(Message,long) |
将消息在特定时间后添加到消息队列挂起消息末尾 |
removeCallbacks() |
将Runnable从消息队列中删除,使线程停止运行 |
obtainMessage() |
从全局消息池中获取一个新的消息,比创建分配新的实例更高效 |
msg.sendToTarget() |
将消息发送到消息队列 |
Message对象携带数据,通常用arg1,arg2来传递消息,还可以传递object对象
MessageQueue就是一个消息队列,可以添加消息,并处理消息
Looper内部包含了一个消息队列MessageQueue,所有的Handler发送的消息都走向这个消息队列。Loooper由系统来控制的循环,一个线程只能有有一个Looper对象。
Looper.Looper方法是一个死循环,不断的从MessageQueue取消息,如果有消息就处理,如果没消息就阻塞
Looper.prepare() 将当前线程初始化为looper。
Looper.loop()在此线程中开始循环处理消息队列,一顶要调用quit()来结束循环
Handler封装了消息的发送,内部会跟Looper进行关联,也就是说在Handler的内部可以找到Looper,找到Looper也就找到了MessageQueue,在Handler中发送消息,其实是向MessageQueue队列中发送消息
Handler负责发送消息,Looper负责接收Handler发送的消息,并直接把消息回传给Handler自己,MessageQueue就是一个存储消息的容器
自定义的与线程相关的Handler
HandlerThread解决多线程并发
在主线程给子线程发送消息
更新UI的几种方法
第一种:handler.post
第二种:handler.sendMessage
第三种:runOnUiThread
第四种:view.post
补充
在非UI线程中可以更新UI,因为ViewRootImpl没有实例化时是不会check线程是否为主线程。
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!