Handler异步消息机制实例解析
来源:互联网 发布:自动修改mac地址修改器 编辑:程序博客网 时间:2024/05/19 19:33
用几个简短的例子将Handler相关的知识点整理下,方便以后查阅也方便大家快速掌握本知识点。
名词解释:
Message 是线程之间传递的消息,它可以在内部携带少量信息,用于在不同线程之间交换数据。
MessageQueue 是消息队列,它主要用于存放所有由 Handler发送过来的消息,这部分消息会一直在消息队列中,等待被处理。
Handler 即处理者,它主要用于发送和处理消息。发送消息一般使用 handler 的 sendMessage(),处理消息会调用 handleMessage()。
Looper 是每个线程中 MessageQueue的管家,调用 loop()方法后就会进入到一个无限循环当中,然后每当发现 MessageQueue中存在一条消息,就会将其取出,并传递到 handleMessage()方法当中。
注意:每个线程中只会有一个Looper对象,一个MessageQueue。Handler依附于创建时所在的线程。
下面就用代码示例其中的原理吧~
目标场景:
主线程向子线程发消息,子线程接收到主线程的消息后给主线程发个通知,然后主线程更新UI。
实现步骤:
1,主线程给子线程发消息,子线程接收消息。
既然是子线程接收消息,说明handleMessage是在子线程中。Handler是依附于子线程。代码如下:
private LoopThread loopThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... //开启实现了Runnable接口的子线程 new Thread(loopThread = new LoopThread()).start(); } /** * 通过实现Runnable接口的方式生成一个子线程 */ public class LoopThread implements Runnable { public Handler mHandler = null; @Override public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { handleMsgAndTodo(msg); } }; Looper.loop(); } }
一个实现了Runnable接口的子线程,在子线程中实例化了handler并通过handleMessage接收消息。注意此处有Looper.prepare();和 Looper.loop();说明是子线程自身新建的消息管家looper(主线程里默认建立了自己的looper)。
主线程发消息就可以直接调用”loopThread.mHandler.sendEmptyMessage(1);”(LoopThread是一个实现了Runnable接口的类)。
接下来子线程接受处理消息与主线程处理消息都封装handleMsgAndTodo(msg)方法中了。代码如下:
/** * 对接收到的消息进行处理 * @param msg */ private void handleMsgAndTodo(Message msg) { switch (msg.what) { case 0: showMessageTv.setText("2---这是更新后的UI"); Log.d("从子线程发消息到主线程", "接收成功"); break; case 1: Log.d("从主线程发消息到子线程", "接收成功"); handler.sendEmptyMessage(0); Log.d("从子线程发消息到主线程", "准备发送"); break; default: break; } }
刚刚主线程发的消息msg.what = 1,这里接收到消息立即给主线程发消息msg.what = 0,注意用的是handler而不是mHandler或者loopThread.mHandler,这里的handler是在主线程中实例化。代码如下:
/** * 接收异步消息更新UI */ Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); handleMsgAndTodo(msg); } };
此处的handler是依附于主线程的,可以直接在其中更新UI。
另外,还有几个方法也是基于异步消息机制。
比如在子线程中更新UI的例子:
/** * 调用hander.post()方法更新主线程UI */ private void handerpost() { new Thread(new Runnable() { @Override public void run() { //...省略进行的耗时操作代码,以下三种方法实现子线程给主线程发消息// handler.sendEmptyMessage(0); //这几个方法在子线程中更新UI等效于在主线程中调用handleMessage()更新UI——hander.post(),view.post(), runOnUiThread(),其原理都是通过异步消息处理机制实现的。// handler.post(new Runnable() {// @Override// public void run() {// showMessageTv.setText("1---这是更新后的UI");// }// });//在子线程中new Handler(Looper.getMainLooper())就表示其handleMessage()方法里的事情是在主UI线程去处理的,这个Handler其实是与主线程绑定的。 Handler handler2 = new Handler(getMainLooper()){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); showMessageTv.setText("3---这是更新后的UI"); } }; handler2.sendEmptyMessage(0); } }).start(); }
如上几段代码中的方法,无异于都是调用主线程中的handler进行发消息更新UI。另一个在子线程中实例化的handler2,也是因为共用了主线程的looper,即与主线程维护同一个消息队列,所以相当于在主线程更新UI。
自我理解:
哪个线程要接收消息,就在该线程实例化Handler来调用handleMessage。若主线程向子线程发消息,则需要用到 Looper.prepare()和 Looper.loop(),并在子线程中实例化Handler来调用handleMessage()。
在子线程中new Handler(Looper.getMainLooper())就表示其handleMessage()方法里的事情是在主UI线程去处理的,这个Handler其实是与主线程绑定的。
hander.post(),view.post(), runOnUiThread()这几个方法在子线程中更新UI等效于在主线程中调用handleMessage更新UI——其原理都是通过异步消息处理机制实现的。
Handler+Thread与HandlerThread区别:
HandlerThread就是将含有消息队列的Looper与Thread封装在一起的写法,可以直接在子线程的接受的消息处理耗时任务。
Handler+Thread与 AsyncTask优缺点:
1,AsyncTask,是Android提供的轻量级的异步类,直接继承AsyncTask类进行异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.
使用的优点:简单,快捷(只是代码上轻量一些,而实际上要比handler更耗资源),过程可控
使用的缺点:在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.
2,Handler+Thread
结构清晰,功能定义明确
对于多个后台任务时,简单,清晰
使用的缺点:在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)
- Handler异步消息机制实例解析
- 解析异步消息处理机制(Handler)
- 异步消息处理机制Handler源码解析
- Android异步消息处理机制Handler完全解析
- Handler:Android异步消息处理机制完全解析
- Handler和异步消息处理机制的解析!!
- 异步消息处理机制(Handler 、 Looper 、MessageQueue)源码解析
- Android异步消息处理机制完全解析-Handler详解
- Android Handler 异步消息机制
- Android Handler 异步消息机制
- Android Handler 异步消息机制
- Android Handler 异步消息机制
- Android Handler 异步消息机制
- Android Handler 异步消息机制
- Handler--异步消息处理机制
- 解析Handler异步消息处理!
- Handler消息机制源码解析
- Handler消息机制源码解析
- Mac上编译opencv源码
- 开源组件使用程度认识
- 关于链接中的堆排序算法,如果认真分析的话,会发现问题
- The function of include in Verilog
- apache digester:
- Handler异步消息机制实例解析
- Zookeeper-HA-配置文件(配置粘贴)
- akka的中文文档:
- 介绍一个node调试工具--nodemon
- springmvc4整合AJAX使用@ResponseBody注解返回JSON数据格式
- RandomAccessFile和内存映射文件?
- SAP HANA 2新特性
- Zookeeper-HA-配置文件(详解)及启动步骤
- 子网掩码: