当前位置:操作系统 > 安卓/Android >>

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 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,