Android消息处理机制(Looper,Handler,MessageQueue笔记)
来源:互联网 发布:三三复制系统源码 编辑:程序博客网 时间:2024/06/06 02:39
定义:
Message:消息,包含ID,消息处理对象及消息数据,由MessageQueue统一管理,最总由Handler处理
Handler:消息处理者,负责Message的发送及处理。
MessageQueue:消息对象,用来存放Handler发送过来的消息,按FIFO顺序。
Looper:消息循环者,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。
三者关系如下:
上图详细说明了消息处理的整个流程。
以下使用handler消息机制时的几个要点:
1.handler可以在任意线程发送消息(UI主线程或者工作线程),这些消息会被添加到关联的MQ上。
2.handler是在它关联的looper线程中处理消息的。
android 主线程也是一个Looper线程,所以普通的做法就是在主线程中new handler对象出来,然后使用这个hanlder来发送和处理消息,并直接可以在当前的主线程中更新UI界面。
所以利用handler一个常用的解决方案是Activity中创建handler,并将引用传递给worker thread(工作线程),工作线程执行完异步任务后使用handler发送消息,通知UI更新界面。
下面一个简单的例子:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/handler" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="handler message " /></LinearLayout>
/** * Copyright (C) 2012 HongCheng System Inc. */package com.android.handler;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.widget.TextView;/** * @author yangjp * @version V1.0 */public class HandlerActivity extends Activity {private TextView textView = null;private Handler handler = null;/* * (non Javadoc)<p>Title: onCreate</p><p>Description: </p> * * @param savedInstanceState * * @see android.app.Activity#onCreate(android.os.Bundle) */@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.handler);textView = (TextView)findViewById(R.id.handler);handler = new MyHandler(textView);Thread thread = new WorkerThread(handler);thread.start();}/** * 工作线程 *@authoryangjp *@versionV1.0 */private class WorkerThread extends Thread{ private Handler handler = null; public WorkerThread(Handler handler){ this.handler = handler; }public void run() { try {Thread.sleep(1000 * 5);// 暂停5秒Message message = handler.obtainMessage();message.what = 1;message.arg1 = 100;handler.sendMessage(message);} catch (InterruptedException e) {e.printStackTrace();}}}/** * 消息处理者 *@authoryangjp *@versionV1.0 */private class MyHandler extends Handler{private TextView textView = null;public MyHandler(TextView textView){this.textView = textView;}/*(non Javadoc) *<p>Title: handleMessage</p> *<p>Description: </p> *@param msg *@see android.os.Handler#handleMessage(android.os.Message) */@Overridepublic void handleMessage(Message msg) {// 处理消息,更新UI界面switch(msg.what){case 1:String result = "执行结果进度:" + msg.arg1;textView.setText(result);break;}}}}
在主线程(UI线程)里,如果创建Handler时不传入Looper对象,那么将直接使用主线程(UI线程)的Looper对象(系统已经帮我们创建了);在其它线程里,如果创建Handler时不传入Looper对象,那么,这个Handler将不能接收处理消息。在这种情况下,通用的作法是:
class LooperThread extends Thread { public Handler mHandler; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; Looper.loop(); } }
在创建Handler之前,为该线程准备好一个Looper(Looper.prepare),然后让这个Looper跑起来(Looper.loop),抽取Message,这样,Handler才能正常工作。
因此,Handler处理消息总是在创建Handler的线程里运行。而我们的消息处理中,不乏更新UI的操作,不正确的线程直接更新UI将引发异常。因此,需要时刻关心Handler在哪个线程里创建的。
1.Activity.runOnUiThread(Runnable)
2.View.post(Runnable)
3.View.postDelayed(Runnable, long)
4.Handler
注意:在post(Runnable action)方法里,View获得当前线程(即UI线程)的Handler,然后将action对象post到Handler里。在Handler里,它将传递过来的action对象包装成一个Message(Message的callback为action),然后将其投入UI线程的消息循环中。在Handler再次处理该Message时,有一条分支(未解释的那条)就是为它所设,直接调用runnable的run方法。而此时,已经路由到UI线程里,因此,我们可以毫无顾虑的来更新UI。
不确定当前线程时,更新UI时尽量调用post方法。
- Android消息处理机制(Looper,Handler,MessageQueue笔记)
- Android消息处理机制:Looper,MessageQueue,Handler
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- Android消息处理机制(Handler、Looper、MessageQueue与Message)
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- 解析Android消息处理机制:Handler/Thread/Looper & MessageQueue
- Android消息处理机制(Handler、Looper、MessageQueue与Message)
- CXF:服务接口(RESTful风格)设计中的注解(Annotation)
- C语言 修改文件 一部分内容
- MQ 连接超时设置
- byte[] to int64
- compareToIgnoreSpaces(char[] charArray, char[] anotherCharArray) {
- Android消息处理机制(Looper,Handler,MessageQueue笔记)
- "The length of the string value exceeds the length configured in the mapping/parameter."}
- compareToIgnoreSpaces(byte[] byteArray, char[] anotherCharArray) {
- CheckStyle
- 2014再次出发
- JS中offsetTop、clientTop、scrollTop、offsetTop各属性介绍
- 我和领导的对比
- what is the difference between ARM7 and ARM7s
- emmc