- 浏览: 110944 次
- 性别:
- 来自: 武汉
文章分类
- 全部博客 (98)
- java (27)
- jms (2)
- jta (0)
- 性能调优及内存分析 (4)
- 设计模式 (14)
- 框架 (6)
- 其它 (9)
- job (1)
- maven (1)
- 服务器 (2)
- 分布式 (3)
- ibatis (1)
- linux (0)
- mysql (0)
- 并发编程 (0)
- java多线程 (2)
- 前端跨域 (1)
- 线程dump分析 (0)
- velocity (0)
- 数据库 (2)
- 协议 (0)
- 监控 (0)
- 开源软件 (2)
- 算法 (0)
- 网络 (1)
- spring (1)
- 编码 (0)
- 数据结构 (0)
- HTable和HTablePool使用注意事项 (0)
- opencms (0)
- android (16)
- 操作系统 (2)
- top (0)
最新评论
-
hold_on:
@Override public boolea ...
android listview的HeadView左右切换图片(仿新浪,网易,百度等切换图片) -
achersnake:
123
Servlet中listener(监听器)和filter的总结 -
angel243fly:
我用了这个方法,还是报同样的错误,还有什么建议吗?
eclipse提示CreateProcess error=87错误的解决方法
在《Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面》中,我们讲到使用Thread+Handler的方式来实现界面的更新,其实是在非UI线程发送消息到UI线程,通知UI线程进行界面更新,这一篇我们将深入学习Android线程间通讯的实现原理。
概述:Android使用消息机制实现线程间的通信,线程通过Looper建立自己的消息循环,MessageQueue是FIFO的消息队列,Looper负责从MessageQueue中取出消息,并且分发到消息指定目标Handler对象。Handler对象绑定到线程的局部变量Looper,封装了发送消息和处理消息的接口。
例子:在介绍原理之前,我们先介绍Android线程通讯的一个例子,这个例子实现点击按钮之后从主线程发送消息"hello"到另外一个名为” CustomThread”的线程。
LooperThreadActivity.java
- package com.zhuozhuo;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Looper;
- import android.os.Message;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- public class LooperThreadActivity extends Activity{
- /** Called when the activity is first created. */
- private final int MSG_HELLO = 0;
- private Handler mHandler;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- new CustomThread().start();//新建并启动CustomThread实例
- findViewById(R.id.send_btn).setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {//点击界面时发送消息
- String str = "hello";
- Log.d("Test", "MainThread is ready to send msg:" + str);
- mHandler.obtainMessage(MSG_HELLO, str).sendToTarget();//发送消息到CustomThread实例
- }
- });
- }
- class CustomThread extends Thread {
- @Override
- public void run() {
- //建立消息循环的步骤
- Looper.prepare();//1、初始化Looper
- mHandler = new Handler(){//2、绑定handler到CustomThread实例的Looper对象
- public void handleMessage (Message msg) {//3、定义处理消息的方法
- switch(msg.what) {
- case MSG_HELLO:
- Log.d("Test", "CustomThread receive msg:" + (String) msg.obj);
- }
- }
- };
- Looper.loop();//4、启动消息循环
- }
- }
- }
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
- <Button android:text="发送消息" android:id="@+id/send_btn" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
- </LinearLayout>
Log打印结果:
原理:
我们看到,为一个线程建立消息循环有四个步骤:
1、 初始化Looper
2、 绑定handler到CustomThread实例的Looper对象
3、 定义处理消息的方法
4、 启动消息循环
下面我们以这个例子为线索,深入Android源代码,说明Android Framework是如何建立消息循环,并对消息进行分发的。
1、 初始化Looper : Looper.prepare()
Looper.java
- private static final ThreadLocal sThreadLocal = new ThreadLocal();
- public static final void prepare() {
- if (sThreadLocal.get() != null) {
- throw new RuntimeException("Only one Looper may be created per thread");
- }
- sThreadLocal.set(new Looper());
- }
一个线程在调用Looper的静态方法prepare()时,这个线程会新建一个Looper对象,并放入到线程的局部变量中,而这个变量是不和其他线程共享的(关于ThreadLocal的介绍)。下面我们看看Looper()这个构造函数:
Looper.java
- final MessageQueue mQueue;
- private Looper() {
- mQueue = new MessageQueue();
- mRun = true;
- mThread = Thread.currentThread();
- }
可以看到在Looper的构造函数中,创建了一个消息队列对象mQueue,此时,调用Looper. prepare()的线程就建立起一个消息循环的对象(此时还没开始进行消息循环)。
2、 绑定handler到CustomThread实例的Looper对象 : mHandler= new Handler()
Handler.java
- final MessageQueue mQueue;
- final Looper mLooper;
- public Handler() {
- if (FIND_POTENTIAL_LEAKS) {
- final Class<? extends Handler> klass = getClass();
- if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
- (klass.getModifiers() & Modifier.STATIC) == 0) {
- Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
- klass.getCanonicalName());
- }
- }
- mLooper = Looper.myLooper();
- if (mLooper == null) {
- throw new RuntimeException(
- "Can't create handler inside thread that has not called Looper.prepare()");
- }
- mQueue = mLooper.mQueue;
- mCallback = null;
- }
Handler通过mLooper = Looper.myLooper();绑定到线程的局部变量Looper上去,同时Handler通过mQueue =mLooper.mQueue;获得线程的消息队列。此时,Handler就绑定到创建此Handler对象的线程的消息队列上了。
3、定义处理消息的方法:Override public void handleMessage (Message msg){}子类需要覆盖这个方法,实现接受到消息后的处理方法。
4、启动消息循环 : Looper.loop()
所有准备工作都准备好了,是时候启动消息循环了!Looper的静态方法loop()实现了消息循环。
Looper.java
- public static final void loop() {
- Looper me = myLooper();
- MessageQueue queue = me.mQueue;
- // Make sure the identity of this thread is that of the local process,
- // and keep track of what that identity token actually is.
- Binder.clearCallingIdentity();
- final long ident = Binder.clearCallingIdentity();
- while (true) {
- Message msg = queue.next(); // might block
- //if (!me.mRun) {
- // break;
- //}
- if (msg != null) {
- if (msg.target == null) {
- // No target is a magic identifier for the quit message.
- return;
- }
- if (me.mLogging!= null) me.mLogging.println(
- ">>>>> Dispatching to " + msg.target + " "
- + msg.callback + ": " + msg.what
- );
- msg.target.dispatchMessage(msg);
- if (me.mLogging!= null) me.mLogging.println(
- "<<<<< Finished to " + msg.target + " "
- + msg.callback);
- // Make sure that during the course of dispatching the
- // identity of the thread wasn't corrupted.
- final long newIdent = Binder.clearCallingIdentity();
- if (ident != newIdent) {
- Log.wtf("Looper", "Thread identity changed from 0x"
- + Long.toHexString(ident) + " to 0x"
- + Long.toHexString(newIdent) + " while dispatching to "
- + msg.target.getClass().getName() + " "
- + msg.callback + " what=" + msg.what);
- }
- msg.recycle();
- }
- }
- }
while(true)体现了消息循环中的“循环“,Looper会在循环体中调用queue.next()获取消息队列中需要处理的下一条消息。当msg != null且msg.target != null时,调用msg.target.dispatchMessage(msg);分发消息,当分发完成后,调用msg.recycle();回收消息。
msg.target是一个handler对象,表示需要处理这个消息的handler对象。Handler的void dispatchMessage(Message msg)方法如下:
Handler.java
- public void dispatchMessage(Message msg) {
- if (msg.callback != null) {
- handleCallback(msg);
- } else {
- if (mCallback != null) {
- if (mCallback.handleMessage(msg)) {
- return;
- }
- }
- handleMessage(msg);
- }
- }
可见,当msg.callback== null 并且mCallback == null时,这个例子是由handleMessage(msg);处理消息,上面我们说到子类覆盖这个方法可以实现消息的具体处理过程。
总结:从上面的分析过程可知,消息循环的核心是Looper,Looper持有消息队列MessageQueue对象,一个线程可以把Looper设为该线程的局部变量,这就相当于这个线程建立了一个对应的消息队列。Handler的作用就是封装发送消息和处理消息的过程,让其他线程只需要操作Handler就可以发消息给创建Handler的线程。由此可以知道,在上一篇《Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面》中,UI线程在创建的时候就建立了消息循环(在ActivityThread的public static final void main(String[] args)方法中实现),因此我们可以在其他线程给UI线程的handler发送消息,达到更新UI的目的。
本博文地址:http://blog.csdn.net/mylzc/article/details/6771331 转载请注明出处
发表评论
-
android listview的HeadView左右切换图片(仿新浪,网易,百度等切换图片)
2013-01-15 20:02 2868http://blog.csdn.net/jj120522 ... -
Maven Android Plugin
2013-01-06 16:20 1592Maven Android Plugin h ... -
解决Android模拟器无法用PC键盘输入与模拟器外部功能添加.
2013-01-06 16:20 1457公司发了PC后重新装了Android开发环境. 但是在模拟器上 ... -
Android Fragment使用
2012-12-20 17:29 866你可以像为View一样, 为fragment指定lay ... -
Android异步处理四:AsyncTask的实现原理
2012-12-14 09:08 989在《Android异步处理二:使用AsyncTask异步 ... -
Android异步处理二:使用AsyncTask异步更新UI界面
2012-12-14 09:00 1029在《Android异步处理一:使用Thread+Hand ... -
Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面
2012-12-14 08:48 1007概述:每个Android应用程序都运行在一个dalvik ... -
Android 中LayoutInflater的使用
2012-12-11 20:11 0大家好我们这一节讲的是LayoutInflater的使用,在实 ... -
邵洋江 android之tabhost讲解
2012-12-11 19:15 0Tab标签页是界面设计时经常使用的界面控件,可以实现多个分页之 ... -
android Bitmap用法总结
2012-12-10 13:09 0android Bitmap用法总结 http://ww ... -
Parcelable接口应用
2012-11-30 19:53 0Android中Intent传递对象有两个方法,一个是让 ... -
常用的android弹出对话框
2012-11-09 08:47 0http://blog.csdn.net/chenlei ... -
Android实现推送方式解决方案
2012-11-07 13:44 0转:http://www.cnblogs.com/han ... -
Android 之 下拉框(Spinner)的使用
2012-11-06 15:16 0下拉列表 Spinner。 Spinner的使用,可以极 ... -
android ListView添加事件并获取选中项的值
2012-11-05 11:45 0转:http://www.beijibear.com/?aid ... -
Android 用TextView做菜单的多个onClick事件的处理
2012-11-02 19:23 0TextView控件使用OnClick事件监听的时候,会遇到一 ... -
在ListView中显示网络图片
2012-11-02 08:30 1110最近在做一个天气预报的例子,想在ListView中添加网 ... -
android ListView详解
2012-11-01 09:43 0在android开发中ListView是比较常用的组件, ... -
Android用Application设置全局变量以及使用
2012-10-21 14:08 937如果想在整个应用中使用全局变量,在java中一般是使用静态 ... -
TabSpec和TabHost实例
2012-10-15 08:44 1572TabSpec与TabHost TabHost相当于 ...
相关推荐
Android 异步处理 Handler+Looper+MessageQueue深入详解
Handler+Looper+MessageQueue
Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面。
作用: 跨线程通信,异步通信。...MessageQueue(消息队列):由Looper负责管理,管理Handler发送过来的Message,其底层实现采用的是单链表。 Handler(处理者):负责Message的发送及处理。通过 Handler.send
3.3.5 errorhandler接口 73 3.3.6 使用sax解析xml文档实例 74 3.4 jdom 83 3.4.1 下载并配置jdom 83 3.4.2 jdom api介绍 84 3.5 dom4j 88 3.5.1 下载并配置dom4j 88 3.5.2 dom4j api介绍 88 3.5.3 第一个...
handler与looper及messagequeue的简单总结
Message,MessageQueue,Looper,Handler详解
这次项目用到的主要是Handler Thread Looper,希望对这三者关系还不是很清楚的人能通过我的项目读懂,当然我也不敢保证一定能
ndroid异步处理一:使用Thread+Handler实现非UI线程更新UI界面
Handler获取当前线程中的looper对象,looper用来从存放Message的MessageQueue中取出Message,再有Handler进行Message的分发和处理. 简单定义: 1、Message Queue(消息队列): 用来存放通过Handler发布的消息,通常...
本篇文章是对Handler,Looper与MessageQueue进行了详细的分析介绍,需要的朋友参考下
Looper MessageQueue 源码解析,通过源码 手写一套自己的Handler。
3.3.5 errorhandler接口 73 3.3.6 使用sax解析xml文档实例 74 3.4 jdom 83 3.4.1 下载并配置jdom 83 3.4.2 jdom api介绍 84 3.5 dom4j 88 3.5.1 下载并配置dom4j 88 3.5.2 dom4j api介绍 88 3.5.3 第一个...
Handler和looper详解.
你可以诞生Handler之对象来与Looper沟通,以便push新讯息到Message Queue里;或者接收Looper(从Message Queue取出)所送来的讯息。 线程A的Handler对象参考可以传递给别的线程,让别的线程B或C等能送讯息来给...
全书一共被压缩为5个rar,这是第三个!!!! 其他的请看ID:ljtt123(本人分享) 本博客提供的所有教程的资源原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何...
android源码中包含了...android的消息处理有三个核心类: Looper,Handler和Message。 其实还有一个Message Queue(消息队列) , 但是MQ被封装到Looper里面了, 我们不会直接与 MQ打交道, 因此我没将其作为核心类。
异步请求分页示例:handler.ashx + $.ajax() + Json + 前端分页处理
在主线程即UI线程外,新建一个Looper线程,并用Messenger和Handler来处理message和posted runnable。程序中,在负线程中默认加了一个3s的线程等来,来帮助理解sent message和post runnable之间的同步机制。所以在按...
Android ,Handler,Looper,Message