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。