Handler、Looper、MessageQueue的工作原理

来源:互联网 发布:urp 数据库更改 编辑:程序博客网 时间:2024/06/15 16:37

对《疯狂Android讲义》内容的总结:

为了保证线程中有Looper对象,分为以下两种情况进行处理:

1、主UI线程中,系统已经初始化了一个Looper对象,程序直接创建Handler即可,然后通过Handler进行消息的发送和处理;

2、启动的子线程,先Looper.prepare()创建Looper对象,然后调用Looper.loop()启动Looper对象。

Looper、MessageQueue、Handler各自的作用:

1、Looper:每个线程只能有一个Looper,他负责管理MessageQueue,会不断的从MessageQueue中取出消息,并将消息分发给对应的Handler进行处理。

2、MessageQueue:由Looper负责管理。采用先进先出的方式管理Message。

3、Handler:将消息发送给由Looper管理的MessageQueue,并负责处理Looper分给它的消息。

在启动的子线程中使用Handler的步骤:

1、调用Looper的prepare()方法为当前线程创建Looper对象,创建Looper对象时,它的构造器会创建与之配套的MessageQueue。

2、有了Looper之后,创建Handler子类的实例,重写handlerMessage()方法,该方法负责处理来自于其他线程的消息。

3、调用Looper的loop()方法启动Looper。

实例:

class NewThread extends Thread{Handler myHandler;public void run(){Looper.prepare();myHandler=new Handler(){public void handleMessage(android.os.Message msg) {//do something}};Looper.loop();}}

-------------------------------------------------------------------------------------------------

示例:

public class TestMainActivity extends Activity {private TextView show1,show2;private Handler handler1,handler2;private Message msg;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);msg=new Message();Bundle b=new Bundle();b.putString("flag", "main");msg.setData(b);show1=(TextView) findViewById(R.id.show1);show2=(TextView) findViewById(R.id.show2);handler1=new Handler(){public void handleMessage(android.os.Message msg) {Bundle b=msg.getData();show1.setText("show1:"+b.getString("flag"));}};handler2=new Handler(){@Overridepublic void handleMessage(Message msg) {Bundle b=msg.getData();show2.setText("show2:"+b.getString("flag"));}};}public void btn1(View view){new Thread(new Runnable(){public void run() {System.out.println("btn1.sendMessage1="+handler1.sendMessage(msg));//System.out.println("btn1.sendMessage2="+handler2.sendMessage(msg));}}).start();}public void btn2(View view){new Thread(new Runnable(){public void run() {System.out.println("btn2.sendMessage="+handler2.sendMessage(msg));}}).start();}}

两个handler发送同一个消息到消息队列,如果先使用handler1发送消息,那么再使用handler2发送消息后,取出的值是null(此时,在handler2发送消息之前,取出消息的getData,发现是null);如果先使用handler2发送消息,那么再使用handler1发送消息后,取出的值也是空(我觉得可能是第一个handler发送消息,并且调用handleMessage方法处理,handlerMessage方法结束后,消息被置空了。);如果向btn1方法中的handler1和handler2先后发送同一个消息,会报错,如果发送不同消息,则正常。

几点小结
1、Handler的处理过程运行在创建Handler的线程里
2、一个Looper对应一个MessageQueue
3、一个线程对应一个Looper
4、一个Looper可以对应多个Handler
5、不确定当前线程时,更新UI时尽量调用postInvalidate方法

0 0
原创粉丝点击