Handler与Looper,MessageQueue的关系
来源:互联网 发布:安卓滤镜软件 编辑:程序博客网 时间:2024/06/05 10:15
Handler与Looper,MessageQueue的关系
总结一下Handler与Looper,MessageQueue的关系,并实现自定义与子线程相关的Handler。
一、Handler与Looper,MessageQueue的关系
它们之间的关系其实就是下面的三条说明:
(1)Looper:相当于消息的载体
• 它的内部有一个消息队列,也就是MessageQueue,Handler发送的所有消息都会走向这个消息队里。
• 它的Looper.loop方法是一个死循环,不断的从消息队列MessageQueue中取出消息。如果有消息存在就处理该消息,否则就阻塞。
(2)MessageQue:就是一个消息队列,可以向其中添加消息并处理消息。
(3)Handler其实就是发送消息处理消息的封装。它与Looper相关联,也就是说在Handler的内部可以找到Looper,找到了Looper就找到了相应的消息队列。因此Handler发送的消息都会走向MessageQueue。
对上面三点说明做一个总结,其实就是:
Handler负责发送消息和接收Looper传过来的消息,并根据消息处理相应逻辑Looper负责接收Handler发送过来的消息,并将该消息回传给Handler自己。而MessageQueue只是相当于一个消息容器
经过上面的说明,对android中的Handler消息处理机制应该有了一个大致的了解了。那么你肯定还有疑问,为什么处理消息要严格这样子做呢?这个问题其实就是为什么不能在子线程中更新UI的问题。下面就是原因。
为什么不能在子线程中更新UI
我们假设可以在子线程更新UI,那么就会出现这样子的一种况:其中一个子线程更新界面还没有完成,另外一个子线程就又去更新UI了,这样子会造成子UI界面错乱。那么你可能会说,我们可以实行加锁机制啊,让更新UI的代码不能并发执行。如果每一个子线程都加锁,那么毫无疑问程序的性能将会大大下降。因此主要的原因总结起来就是两点:
(1)为了防止界面错乱
(2)为了防止程序性能下降
因此android不允许在子线程中更新UI。为了解决这个这个问题,android就设计出这样子的一套消息处理机制,让我们尽管在子线程中发送更新UI的消息,而不用去关心多线程问题。在主线程的消息队里中采取轮询更新处理。
二、自定义与子线程关联的Handler
了解了Handler与Looper,MessageQueue后,我们可以实现自定义的Handler,该Handler与子线程关联(注意我们创建的默认Handler都是与主线程,即UI线程关联的,因为没有指定Looper,因此如果Looper不存在是不能创建Handler的)。下面我们就来简单实现这个自定义的Handler。新建一个项目,只需要修改它的MainActiivty代码即可,如下:
1 package com.example.handldertest;23 import android.app.Activity;4 import android.os.Bundle;5 import android.os.Handler;6 import android.os.Looper;7 import android.util.Log;8 import android.widget.TextView;910 public class ThreadHandlerActivity extends Activity{111213 //创建子线程14 class MyThread extends Thread{15 private Handler handler;//与该子线程关联的Handler16 public void run() {1718 Looper.prepare();//创建该子线程的Looper19 handler = new Handler(){//默认与当前线程关联20 public void handleMessage(android.os.Message msg) {21 Log.d("当前子线程是----->", Thread.currentThread()+"");22 };23 };2425 Looper.loop();//只要调用了该方法才能不断循环取出消息26 }27 }2829 private TextView tv;30 private MyThread thread;3132 private Handler mHandler = new Handler(){33 public void handleMessage(android.os.Message msg) {34 Log.d("当前主线程是----->", Thread.currentThread()+"");35 };36 };3738 protected void onCreate(Bundle savedInstanceState) {39 super.onCreate(savedInstanceState);40 tv = new TextView(this);41 tv.setText("Handler实验");42 setContentView(tv);4344 thread = new MyThread();45 thread.start();//千万别忘记开启这个线程46 try {47 Thread.sleep(2000);//主线程休眠2秒48 } catch (InterruptedException e) {49 e.printStackTrace();50 }51 //下面用子线程的Handler发送消息52 thread.handler.sendEmptyMessage(1);53 //下面是主线程发送消息54 mHandler.sendEmptyMessage(1);55 }5657 }
在程序的MyThread类中,我们首先创建自己的Looper,然后使用Handler的无参数构造器(无参构造器默认的是与当前线程相关联)。最后千万要记得调用Looper.loop方法,这样子才能让消息队列循环轮询(即是个死循环)。然后在onCreate方法中让主线程休眠2秒后(主要是为了便于观看结果),再让子线程的handler发送消息,当然我了区别的观察结果,我们也建立了一个主线程的Hander,即mHandler,也让它发送了消息。打印的结果如下:
通过打印结果,我们发现打印出来的当前线程ID是不一样的,充分说明handler是与创建的子线程相关联的。总结一下吧。
实现与子线程关联的Handler,必须要:
1. 必须先创建Looper,调用Looper.prepare方法即可2. 实例化Handler,与之关联3. 调用Looper.loop方法,实现循环不断读取消息
上面三步是要放在run方法中编写的。
- Handler与looper、MessageQueue的关系
- Handler与Looper,MessageQueue的关系
- Handler、MessageQueue 、Looper的关系
- Handler Looper MessageQueue 的关系
- Handler,Looper,MessageQueue关系
- Activity/MessageQueue/Handler/Looper之间的关系
- Andriod中Handler,Looper,MessageQueue的关系
- Looper, messageQueue和Handler的关系
- Handler Looper Message MessageQueue 的关系
- Message、Handler、MessageQueue、Looper之间的关系
- handler、looper、messagequeue之间的关系
- Handler Looper MessageQueue 之间的关系
- Android--Handler,Looper,MessageQueue的关系
- Message,Handler,MessageQueue,Looper之间的关系
- 理解Handler、Looper、MessageQueue的关系
- Handler,Looper,Message,MessageQueue的关系
- Message、Handler、MessageQueue、Looper之间的关系
- 详解Message,Handler,MessageQueue,Looper的关系
- 使用Python openpyxl模块读写Excel
- 探讨Dubbo与Swagger的集成
- 《C++ Primer》读书笔记第三章-1-标准库类型string
- 谨以此篇献给正在迷茫的人生 浅谈网络时代各种骗局
- Handler的简单使用介绍
- Handler与Looper,MessageQueue的关系
- 【Leetcode】【python】Substring with Concatenation of All Words
- log
- Ember.js的那些坑
- MaterialDesign设计(下)
- kafka数据可靠性深度解读
- 利用ReLU输出稀疏性加速卷积
- Android AppUasge统计一招制敌
- mutableCopy 与 copy