都是从别的地方摘出来的,认为简单易懂的
http://blog.csdn.net/redoffice/article/details/6729964
一些概念:
Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。
Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。
MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。
Looper:一个线程可以产生一个Looper对象,用来管理MessageQueue,它就像一个消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。
多线程的问题:
当我们启动一个Android应用程序的时候,Android会首先开启一个主线程,这个主线程的工作主要就是管理界面中的UI控件,进行事件分发,处理消息响应函数等。但是如果处理一个比较耗时的操作时,比如读取本地大文档,读取网络数据等等时,如果依然用主线程的话,就会出现问题,Android系统规定默认5S无反应的话,就会弹出强制关闭对话框。
在这个时候我们就需要另外开一个线程来处理耗时的工作,这与在学习SurfaceView的时候,我们开启了一个线程去处理频繁更新的操作有些类似。但是因为子线程涉及到UI更新,而更新UI只能在主线程中更新(Android主线程不是线程安全的),子线程中操作是危险的。Handler就是用来解决这个复杂问题而出现的。Handler运行在主线程中(UI线程中),它与子线程可以通过Message对象来传递数据,这个时候,Handler就承担着接受子线程传过来的(子线程用sendMessage()方法传递)Message对象(里面包含数据),把这些消息放入主线程队列中,配合主线程进行更新UI。
package com.blueeagle; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.TextView; public class SendMessage extends Activity { private TextView textView; private MyHandler myHandler;//定义一个自己的Handle类 private Button button; private MyThread m=new MyThread(); //定义一个自己的线程类 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textView=(TextView)findViewById(R.id.text); button=(Button)findViewById(R.id.startButton); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { myHandler=new MyHandler(); new Thread(m).start(); System.out.println("主线程运行ID:"+Thread.currentThread().getId()); } }); }//在对UI进行更新时,执行时所在的线程为主UI线程 class MyHandler extends Handler{//继承Handler类时,必须重写handleMessage方法 public MyHandler(){ } public MyHandler(Looper l){ super(l); } @Override public void handleMessage(Message msg) {//执行接收到的通知,此时执行的顺序是按照队列进行,即先进先出 super.handleMessage(msg); Bundle b=msg.getData(); String textStr1=b.getString("textStr"); SendMessage.this.textView.setText(textStr1);//更改TextView中的值 } }//该线程将会在单独的线程中运行 class MyThread implements Runnable{ int i=1; @Override public void run() { while(i<11){ System.out.println("当前运行线程ID:"+Thread.currentThread().getId()); try { Thread.sleep(1000); } catch(InterruptedException e){ e.printStackTrace(); } Message msg=new Message(); Bundle b=new Bundle(); b.putString("textStr", "线程运行"+i+"次"); i++; msg.setData(b); SendMessage.this.myHandler.sendMessage(msg);//通过sendMessage向Handler发送更新UI的消息 } i=1;//下次启动线程时重新计数。 } } }
http://blog.csdn.net/android_tutor/article/details/5834246
http://blog.csdn.net/redoffice/article/details/6744803
Handler类的四个构造函数中,都会有如下代码:
mQueue = mLooper.mQueue;
Looper类的构造函数如下:
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
http://blog.csdn.net/L_serein/article/details/6269270
Message Queue:
Message Queue是一个消息队列,用来存放通过Handler发布的消息。Android在第一启动程序时会默认会为UI thread创建一个关联的消息队列,可以通过Looper.myQueue()得到当前线程的消息队列,用来管理程序的一些上层组件,activities,broadcast receivers 等等。你可以在自己的子线程中创建Handler与UI thread通讯。
通过Handler你可以发布或者处理一个消息或者是一个Runnable的实例。每个Handler都会与唯一的一个线程以及该线程的消息队列管理。
Looper扮演着一个Handler和消息队列之间通讯桥梁的角色。程序组件首先通过Handler把消息传递给Looper,Looper把消息放入队列。Looper也把消息队列里的消息广播给所有的Handler,Handler接受到消息后调用handleMessage进行处理。