//
Looper:
在UI主线程里面有默认有一个Looper对象来管理UI线程的各条消息,但是在自定义的实现Thread的消息循环和消息派发,缺省情况下Thread是没有这个消息循环的既没有Looper;需要主动去创建将该线程内部的message添加到messagequeue中去,让looper来进行管理添加到,然后启动Looper的消息循环loop;与外部的交互通过Handler进行;
MessageQueue:
消息队列,由Looper所持有,但是消息的添加是通过Handler进行;
消息循环和消息队列都是属于Thread,而Handler本身并不具有Looper和MessageQueue;
但是消息系统的建立和交互,是Thread将Looper和MessageQueue交给某个Handler维护建立消息系统模型。所以消息系统模型的核心就是Looper。消息循环和消息队列都是由Looper建立的,而建立Handler的关键就是这个Looper。
一个Thread同时可以对应多个Handler,一个Handler同时只能属于一个Thread。Handler属于哪个
Thread取决于Handler在那个Thread中建立。
在一个Thread中Looper也是唯一的,一个Thread对应一个Looper,建立Handler的Looper来自哪个Thread,
Handler属于哪个Thread。
//================首先是让handler有一个需要looper对象的构造来看一下,在主线程里面是不是有一个looper对象。
1 2 3 import android.os.Bundle; 4 import android.os.Handler; 5 import android.os.Looper; 6 import android.os.Message; 7 import android.view.View; 8 import android.widget.Button; 9 import android.widget.TextView; 10 import android.app.Activity; 11 12 public class Main extends Activity { 13 private Button button; 14 private TextView textView; 15 private MyHandler handler; 16 17 @Override 18 protected void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 setContentView(R.layout.main); 21 // 在activity里面有一个默认的Looper对象来处理子线程中发送的消息。 22 button = (Button) findViewById(R.id.button1); 23 textView = (TextView) findViewById(R.id.editText1); 24 // 获取looper 25 Looper looper = Looper.getMainLooper(); // 26 handler = new MyHandler(looper); //通过这个looper传递过去 27 handler = new MyHandler(); ///这个效果和上面的效果执行上是一模一样的。 28 button.setOnClickListener(new View.OnClickListener() { 29 @Override 30 public void onClick(View v) { 31 // TODO Auto-generated method stub 32 new Thread(new MyThread()).start(); 33 } 34 }); 35 } 36 37 // 子线程 38 public class MyThread implements Runnable { 39 @Override 40 public void run() { 41 // TODO Auto-generated method stub 42 Message message = Message.obtain(); 43 message.obj = "LooperMessage"; 44 handler.sendMessage(message); 45 } 46 } 47 48 // 继承一个handler类 49 public class MyHandler extends Handler { 50 public MyHandler() { 51 // TODO Auto-generated constructor stub 52 } 53 54 // 定义一个带参构造方法 55 public MyHandler(Looper looper) { 56 super(looper); 57 } 58 59 @Override 60 public void handleMessage(Message msg) { 61 // TODO Auto-generated method stub 62 super.handleMessage(msg); 63 textView.setText("-接收消息-->" + msg.obj.toString()); 64 } 65 } 66 67 }
// 验证只有加入到messageQueue的消息队列里面handler才可以获取,处理,分发。而这个messageQueue就是有looper进行管理的。
//这个是从UI主线想子线程中发送消息,只要将将要发送的消息加入到looper管理的messageQueue(主线程)队列中去,在同一个消息队列里面处理一个消息不就很easy吗?
1 package com.example.handler_looper_01; 2 3 import android.os.Bundle; 4 import android.os.Handler; 5 import android.os.Looper; 6 import android.os.Message; 7 import android.view.View; 8 import android.widget.Button; 9 import android.widget.TextView; 10 import android.app.Activity; 11 12 /** 13 * 将消息从UI主线程中发送到子线程中,比较少用~~ 14 * 15 * @author lpp 16 * 17 */ 18 public class Main extends Activity { 19 private Button button; 20 private TextView textView; 21 private Handler handler; // 获取handler对象 22 23 @Override 24 protected void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 setContentView(R.layout.main); 27 // 在activity里面有一个默认的Looper对象来处理子线程中发送的消息。 28 button = (Button) findViewById(R.id.button1); 29 textView = (TextView) findViewById(R.id.editText1); 30 // 启动线程 31 new Thread(new MyThread()).start(); 32 button.setOnClickListener(new View.OnClickListener() { 33 @Override 34 public void onClick(View v) { 35 Message message = Message.obtain(); 36 message.obj = "UI的message"; 37 handler.sendMessage(message); 38 } 39 }); 40 } 41 42 // 子线程 43 public class MyThread implements Runnable { 44 @Override 45 public void run() { 46 // 在线程里面与activity不一样是没有looper与之进行关联。因此是无法接收到looper里面的消息!直接报错 47 Looper.prepare(); // 循环消息队列 48 // 接受Ui主线程发送过来的消息 49 handler = new Handler() { 50 @Override 51 public void handleMessage(Message msg) { 52 super.handleMessage(msg); 53 // CalledFromWrongThreadException: Only the original thread 54 // that created a view hierarchy can touch its views. 55 // textView.setText(msg.obj.toString()); // 56 // 这属于在子线程中更新UI,会直接报错! 57 System.out.println(msg.obj.toString()); 58 59 } 60 }; 61 Looper.loop(); // 知道消息队列循环结束 62 } 63 } 64 }
消息循环和消息队列都是属于Thread,而Handler本身并不具有Looper和MessageQueue;
但是消息系统的建立和交互,是Thread将Looper和MessageQueue交给某个Handler维护建立消息系统模型。
所以消息系统模型的核心就是Looper。消息循环和消息队列都是由Looper建立的,
而建立Handler的关键就是这个Looper。
一个Thread同时可以对应多个Handler,一个Handler同时只能属于一个Thread。Handler属于哪个
Thread取决于Handler在那个Thread中建立。
在一个Thread中Looper也是唯一的,一个Thread对应一个Looper,建立Handler的Looper来自哪个Thread,
Handler属于哪个Thread。