Android异步处理三:Handler+Looper+MessageQueue深入详解
在《Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面》http://www.zzzyk.com/kf/201204/127128.html中,我们讲到使用Thread+Handler的方式来实现界面的更新,其实是在非UI线程发送消息到UI线程,通知UI线程进行界面更新,这一篇我们将深入学习Android线程间通讯的实现原理。
概述:Android使用消息机制实现线程间的通信,线程通过Looper建立自己的消息循环,MessageQueue是FIFO的消息队列,Looper负责从MessageQueue中取出消息,并且分发到消息指定目标Handler对象。Handler对象绑定到线程的局部变量Looper,封装了发送消息和处理消息的接口。
例子:在介绍原理之前,我们先介绍Android线程通讯的一个例子,这个例子实现点击按钮之后从主线程发送消息"hello"到另外一个名为” CustomThread”的线程。
代码下载
LooperThreadActivity.java
[java]
1. package com.zhuozhuo;
2.
3. import android.app.Activity;
4. import android.os.Bundle;
5. import android.os.Handler;
6. import android.os.Looper;
7. import android.os.Message;
8. import android.util.Log;
9. import android.view.View;
10. import android.view.View.OnClickListener;
11.
12. public class LooperThreadActivity extends Activity{
13. /** Called when the activity is first created. */
14.
15. private final int MSG_HELLO = 0;
16. private Handler mHandler;
17.
18. @Override
19. public void onCreate(Bundle savedInstanceState) {
20. super.onCreate(savedInstanceState);
21. setContentView(R.layout.main);
22. new CustomThread().start();//新建并启动CustomThread实例
23.
24. findViewById(R.id.send_btn).setOnClickListener(new OnClickListener() {
25.
26. @Override
27. public void onClick(View v) {//点击界面时发送消息
28. String str = "hello";
29. Log.d("Test", "MainThread is ready to send msg:" + str);
30. mHandler.obtainMessage(MSG_HELLO, str).sendToTarget();//发送消息到CustomThread实例
31.
32. }
33. });
34.
35. }
36.
37.
38.
39.
40.
41. class CustomThread extends Thread {
42. @Override
43. public void run() {
44. //建立消息循环的步骤
45. Looper.prepare();//1、初始化Looper
46. mHandler = new Handler(){//2、绑定handler到CustomThread实例的Looper对象
47. public void handleMessage (Message msg) {//3、定义处理消息的方法
48. switch(msg.what) {
49. case MSG_HELLO:
50. Log.d("Test", "CustomThread receive msg:" + (String) msg.obj);
51. }
52. }
53. };
54. Looper.loop();//4、启动消息循环
55. }
56. }
57. }
main.xml
[html]
1. <?xml version="1.0" encoding="utf-8"?>
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3. android:orientation="vertical"
4. android:layout_width="fill_parent"
5. android:layout_height="fill_parent"
6. >
7. <TextView
8. android:layout_width="fill_parent"
9. android:layout_height="wrap_content"
10. android:text="@string/hello"
11. />
12. <Button android:text="发送消息" android:id="@+id/send_btn" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
13. </LinearLayout>
Log打印结果:
原理:
我们看到,为一个线程建立消息循环有四个步骤:
1、 初始化Looper
2、 绑定handler到CustomThread实例的Looper对象
3、 定义处理消息的方法
4、 启动消息循环
下面我们以这个例子为线索,深入Android源代码,说明Android Framework是如何建立消息循环,并对消息进行分发的。
1、 初始化Looper : Looper.prepare()
Looper.java
[java]
1. private static final ThreadLocal sThreadLocal = new ThreadLocal();
2. public static final void prepare() {
3. if (sThreadLocal.get() != null) {
4. throw new RuntimeException("Only one Looper may be created per thread");
5. }
6. sThreadLocal.set(new Looper());
7. }
一个线程在调用Looper的静态方法prepare()时,这
补充:移动开发 , Android ,