Android多线程Handler的使用,基于源代码理解。
来源:互联网 发布:淘宝购物车需求分析 编辑:程序博客网 时间:2024/06/05 19:12
第一次接触Handler的时候一头雾水,当时学到了一半就没有再去接触了,这几天又潜下心来细细的研究了一下,根据Mars的视频和自己的理解。在理解Handler的同时,我们也需要理解其它2个对象。分别是:Looper、Message。
Looper,顾名思义,就是一个循环器,是Handler多线程中重要一环,他的作用主要有以下几点:
1、产生MessageQueue对象对象。在实例化Looper对象的时候,会同时实例化一个MessageQueue对象。
2、取出Message对象,并把取出的Message对象交给先前与Looper相关联的Handler对象。
Message,即消息。这就是我们Handler花九牛二虎之力需要“搬迁”到其它线程的对象。细细看看Android源代码,发现其实他的作用主要也有两点:
1、存放需要传输的数据,如使用Message的obj属性等。
2、关联使用了sendMessage方法的对象。[目的是为了在主线程中和使用handMessage方法的Handler一致]
以上都是我个人的理解,可能有办法有误,小伙伴们可以自己去看源码。SORRY...--.--
基于上面的理解,我们来梳理一般要如何使用Handler来处理多线程。总共方法有三步:
1、初始化Looper。(这一步会产生MessageQueue对象)
2、实例化Handler。(这里要记住在哪个线程new 的Handler,Looper就在哪个线程运行)
3、启动Looper,即使Looper开始循环。
下面,我们基于Android源码来理解这三条。在这之前,大家要知道一点,在主线程中系统已经预设了一个Looper,所以主线程向其它线程发送消息时无需启动Looper,直接实例化Handler对象即可。
可以发现,其实实际方法就是三步。
第一步:Looper.prepare();
public static void prepare() { prepare(true); } private static void prepare(boolean quitAllowed) { //实际是调用本方法。 if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed);//实例化一个消息队列对象 mRun = true; mThread = Thread.currentThread(); }
总结第一步就是我们开始说的,实例化一个Looper和一个消息队列(MessageQueue)对象。
第二步:new 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();//myLooper方法就是从当前线程中取出Looper对象(在Looper.prepare()中存进去的),并把其关联到Handler类中的Looper if (mLooper == null) { throw new RuntimeException( "Can't create handler inside thread that has not called Looper.prepare()"); } mQueue = mLooper.mQueue;//把开始初始化的消息队列关联到Hander类中的队列 mCallback = callback; mAsynchronous = async; }
public static void loop() { final Looper me = myLooper();//从当前线程中取出Looper对象 if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; ... for (;;) { //死循环。不断从消息队列中取出Message对象,为空则阻塞。 Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } // This must be in a local variable, in case a UI event sets the logger Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } msg.target.dispatchMessage(msg);//追究源码可以发现,其实就是回调handleMessage方法。 //msg.target就是一个Handler if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); } .... } msg.recycle(); } }
Handler target; //Message类的成员
public void dispatchMessage(Message msg) { //Handler类 if (msg.callback != null) { handleCallback(msg); } else { if (mCallback != null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg);//回调 } }
第三步总结起来就是使Looper循环,取出Message对象,并使用这个对象,来产生回调。即我们重写的handMessage方法。
第一次写博文,格式就调了1个小时- -请大家海涵。^_^
==========================================================================================================================================================
更新……我还想解释一下,为什么Handler把消息放到MessageQueue中,然后Looper.loop()取出的时候恰好是我们放进去的Handler。
Message msg = Handler.obtainMessage();
这个obtainMessage()其实是把操作它的Handler放到了Message的属性里的。请看源码:
public final Message obtainMessage() { return Message.obtain(this); }再追踪Message的obtain方法:
public static Message obtain(Handler h) { Message m = obtain(); m.target = h; //上面已经说过了,这个m.target就是Hanler,这一步就恰好把Hanlder存入了Message中。 return m; }至于取出,大家可以看上面,在Looper对象中loop方法中
msg.target.dispatchMessage(msg);//这个msg.target不就是开始存进来Handler吗?
- Android多线程Handler的使用,基于源代码理解。
- Android中Handler的使用与理解
- android handler的理解
- Android使用Handler实现多线程
- Android多线程及Handler使用
- android多线程使用实例之AsynTask和handler的使用
- Handler的使用与多线程
- Android中TimerTask与Handler延迟多线程源代码
- 如何利用TimerTask与Handler延迟多线程Android源代码
- TimerTask与Handler延迟多线程操作Android源代码
- Android线程Handler的理解
- Android中的handler的理解
- Android 中handler的理解
- Android中Handler的理解
- Android 多线程:使用Thread和Handler
- Android 多线程handler,runnable,asyctask使用
- android handler的使用
- Android Handler的使用
- error和exception的区别,RuntimeException和非RuntimeException的区别
- PHP的RPC框架:Yar
- Java编程优化之旅(一)一般化方法
- 一个菜鸟初学树莓派(1)
- 菜鸟一样要长大
- Android多线程Handler的使用,基于源代码理解。
- qt入门--一些基础控件的应用
- C++ Primer
- HighCharts之2D半圆环图
- 静态链表
- HDU 2561 第二小整数
- 如何评价谭浩强(转自知乎)
- mysql与oracle的区别
- struts标签<logic:iterate>的用法