Android 消息处理Handler、 Message 、MessageQueue、Looper、Thread协调配合
2013-09-27 11:08
597 查看
android界面控制在ui线程里面,任何子线程都不允许直接操作ui而是借助handler或者activity的post方法等。handler又是如何处理线程间通信的?
1、Handler的声明放在ui主线程中声明然后传递给子线程:
Handler的源码:
我们主要看黑色部分,函数调用 Looper.mylooper(),返回得到一个looper实例。该实例有个mQueue的成员变量属于MessageQueue的类型。
mCallback为null,mAsynchrous 为false 。
callback可以指定message的处理回调,而不是使用handler的默认handMessage()处理消息的回调。
mAsynchrous 表示该handle是否可以处理异步消息目前还不清楚如何区别别的消息类型。
先看下Looper
创建handler的时候便可以通过Looper.mylooper得到当前线程的looper 通过looper可以得到当前线程的消息队列 mMessageQueue 。Handler调用sendMessage的时候将message压入mMessageQueue。到此为止消息已经成功加入到消息队列当中,那么消息是什么时候,怎么样处理地呢?
回头看看Looper这个类,在创建 Handler的时候 Looper.mylooper()这个Looper的静态方法又是如何得到looper的呢。查找looper的成员函数,可以找到我们熟悉的Looper.prepare()以及Looper.prepareMain()由此可断定,当系统启动的时候即当ui主线程创建的时候android 内部便调用了Looper.prepareMainLooper()方法
再调用完此方法后便调用Looper.looper()方法,详情参考android源码。可以看到looper方法里面有个循环不断的从mMessageQueue里面拿出消息,再交由message的target的dispatchMessage处理。message的target是一个handler对象,在加入mMessageQueue的时候添加:
disPatchMessage方法如下:
Message 自己有callback是一个runable ,handler也有个Callback 是一个handler类的内部接口,当希望使用自己接口来处理消息回调,可以实现该内部接口的handleMessage(Message msg) 方法。当处理消息的时候优先使用message的callback 其次使用传入handler的callback,再就是handler的handmessage的方法。
这样一波三折子线程的message通过handler传入到主线程的消息队列中并且在主线中执行。这样便可以在子线程中操作ui线程的东西。
1、Handler的声明放在ui主线程中声明然后传递给子线程:
Handler handler=new Handler() { public void handleMessage(android.os.Message msg) { }; };
Handler的源码:
public Handler() { this(null, false); }
public Handler(Callback callback, boolean async) { 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 = callback; mAsynchronous = async; }
我们主要看黑色部分,函数调用 Looper.mylooper(),返回得到一个looper实例。该实例有个mQueue的成员变量属于MessageQueue的类型。
mCallback为null,mAsynchrous 为false 。
callback可以指定message的处理回调,而不是使用handler的默认handMessage()处理消息的回调。
mAsynchrous 表示该handle是否可以处理异步消息目前还不清楚如何区别别的消息类型。
先看下Looper
public class Looper { private static final String TAG = "Looper"; // sThreadLocal.get() will return null unless you've called prepare(). static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); private static Looper sMainLooper; // guarded by Looper.class final MessageQueue mQueue; final Thread mThread; volatile boolean mRun; private Printer mLogging;
创建handler的时候便可以通过Looper.mylooper得到当前线程的looper 通过looper可以得到当前线程的消息队列 mMessageQueue 。Handler调用sendMessage的时候将message压入mMessageQueue。到此为止消息已经成功加入到消息队列当中,那么消息是什么时候,怎么样处理地呢?
回头看看Looper这个类,在创建 Handler的时候 Looper.mylooper()这个Looper的静态方法又是如何得到looper的呢。查找looper的成员函数,可以找到我们熟悉的Looper.prepare()以及Looper.prepareMain()由此可断定,当系统启动的时候即当ui主线程创建的时候android 内部便调用了Looper.prepareMainLooper()方法
/** * Initialize the current thread as a looper, marking it as an * application's main looper. The main looper for your application * is created by the Android environment, so you should never need * to call this function yourself. See also: {@link #prepare()} */ public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } }
再调用完此方法后便调用Looper.looper()方法,详情参考android源码。可以看到looper方法里面有个循环不断的从mMessageQueue里面拿出消息,再交由message的target的dispatchMessage处理。message的target是一个handler对象,在加入mMessageQueue的时候添加:
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) { msg.target = this; if (mAsynchronous) { msg.setAsynchronous(true); } return queue.enqueueMessage(msg, uptimeMillis); }
disPatchMessage方法如下:
/** * Handle system messages here. */ public void dispatchMessage(Message msg) { if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }
Message 自己有callback是一个runable ,handler也有个Callback 是一个handler类的内部接口,当希望使用自己接口来处理消息回调,可以实现该内部接口的handleMessage(Message msg) 方法。当处理消息的时候优先使用message的callback 其次使用传入handler的callback,再就是handler的handmessage的方法。
这样一波三折子线程的message通过handler传入到主线程的消息队列中并且在主线中执行。这样便可以在子线程中操作ui线程的东西。
相关文章推荐
- UITextField介绍
- 使元素hasLayout属性值为true的方法
- Guice学习资料
- 给查询界面绑定query
- Java GUI:图形用户界面三剑客相比拼
- Servlet乱码——request
- 在EditUI类里面刷新单据数据
- UIView的生命周期 init、loadView、viewDidLoad、viewDidUnload、dealloc
- IOS-- UIView中的坐标转换
- Minigui3.0.12移植到nuc951上
- EXP-00091: Exporting questionable statistics.问题解决
- UIDatePicker中英文显示
- ios7适配--uitableviewcell选中效果
- eas bos editUI 刷新方法 帮助类
- WITH AS短语,也叫做子查询部分(subquery factoring)
- 如何用在代码中通过query接口来取结果集。
- JAVA UUID 生成
- JSP学习笔记3-getRequestDispatcher()与sendRedirect()的区别
- Android 自动生成build.xml
- <one-to-one name="iUser" constrained="true"></one-to-one> 的含义