`
gogoalong
  • 浏览: 49692 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

[Android源码]分析之Looper

 
阅读更多

Looper的字面意思是“循环者”,它被设计用来使一个普通线程变成Looper线程。所谓Looper线程就是循环工作的线程。在程序开发中(尤其是GUI开发中),我们经常会需要一个线程不断循环,一旦有新任务则执行,执行完继续等待下一个任务,这就是Looper线程。使用Looper类创建Looper线程很简单:

class LooperThread extends Thread {
    public Handler mHandler;
  
    public void run() {
        Looper.prepare();
  
        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                // process incoming messages here
            }
        };
  
        Looper.loop();
        }
    }
}

通过上面两行核心代码,你的线程就升级为Looper线程了!!!是不是很神奇?让我们放慢镜头,看看这两行代码各自做了什么。

1)Looper.prepare()


通过上图可以看到,现在你的线程中有一个Looper对象,它的内部维护了一个消息队列MQ。注意,一个Thread只能有一个Looper对象,为什么呢?咱们来看源码。

public class Looper {
    // 每个线程中的Looper对象其实是一个ThreadLocal,即线程本地存储(TLS)对象
    private static final ThreadLocal sThreadLocal = new ThreadLocal();
    // Looper内的消息队列
    final MessageQueue mQueue;
    // 当前线程
    Thread mThread;
    // 。。。其他属性

    // 每个Looper对象中有它的消息队列,和它所属的线程
    private Looper() {
        mQueue = new MessageQueue();
        mRun = true;
        mThread = Thread.currentThread();
    }

    // 我们调用该方法会在调用线程的TLS中创建Looper对象
    public static final void prepare() {
        if (sThreadLocal.get() != null) {
            // 试图在有Looper的线程中再次创建Looper将抛出异常
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());
    }
    // 其他方法
}

通过源码,prepare()背后的工作方式一目了然,其核心就是将looper对象定义为ThreadLocal。如果你还不清楚什么是ThreadLocal,请参考《理解ThreadLocal》

2)Looper.loop()



调用loop方法后,Looper线程就开始真正工作了,它不断从自己的MQ中取出队头的消息(也叫任务)执行。其源码分析如下:

public static final void loop() {
        Looper me = myLooper();  //得到当前线程Looper
        MessageQueue queue = me.mQueue;  //得到当前looper的MQ
        
        // 这两行没看懂= = 不过不影响理解
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();
        // 开始循环
        while (true) {
            Message msg = queue.next(); // 取出message
            if (msg != null) {
                if (msg.target == null) {
                    // message没有target为结束信号,退出循环
                    return;
                }
                // 日志。。。
                if (me.mLogging!= null) me.mLogging.println(
                        ">>>>> Dispatching to " + msg.target + " "
                        + msg.callback + ": " + msg.what
                        );
                // 非常重要!将真正的处理工作交给message的target,即后面要讲的handler
                msg.target.dispatchMessage(msg);
                // 还是日志。。。
                if (me.mLogging!= null) me.mLogging.println(
                        "<<<<< Finished to    " + msg.target + " "
                        + msg.callback);
                
                // 下面没看懂,同样不影响理解
                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);
                }
                // 回收message资源
                msg.recycle();
            }
        }
    }

除了prepare()和loop()方法,Looper类还提供了一些有用的方法,比如

Looper.myLooper()得到当前线程looper对象:

    public static final Looper myLooper() {
// 在任意线程调用Looper.myLooper()返回的都是那个线程的looper
return (Looper)sThreadLocal.get();
}

getThread()得到looper对象所属线程:

    public Thread getThread() {
return mThread;
}

quit()方法结束looper循环:

    public void quit() {
// 创建一个空的message,它的target为NULL,表示结束循环消息
Message msg = Message.obtain();
// 发出消息
mQueue.enqueueMessage(msg, 0);
}

Activity以及Service的消息循环结构图。

到此为止,你应该对Looper有了基本的了解,总结几点:

1.每个线程有且最多只能有一个Looper对象,它是一个ThreadLocal

2.Looper内部有一个消息队列,loop()方法调用后线程开始不断从队列中取出消息执行

3.Looper使一个线程变成Looper线程。






分享到:
评论

相关推荐

    安卓Android源码——HandlerLooper2.rar

    这个压缩包“安卓Android源码——HandlerLooper2.rar”可能包含了关于这些组件的深入分析和示例代码。以下是关于`Handler`、`Looper`和`MessageQueue`的详细解释: 1. **Handler**: - `Handler`是Android中的一个...

    Android应用源码之HandlerLooper2.zip项目安卓应用源码下载

    Android应用源码之HandlerLooper2.zip项目安卓应用源码下载Android应用源码之HandlerLooper2.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考

    Android应用源码之HandlerLooper1.zip项目安卓应用源码下载

    Android应用源码之HandlerLooper1.zip项目安卓应用源码下载Android应用源码之HandlerLooper1.zip项目安卓应用源码下载 1.适合学生毕业设计研究参考 2.适合个人学习研究参考 3.适合公司开发项目技术参考

    Android应用源码之HandlerLooper2_Android.zip

    本压缩包"Android应用源码之HandlerLooper2_Android.zip"可能包含了关于这个主题的详细示例代码,让我们深入探讨这些关键组件的工作原理。 首先,`Handler`类是Android中处理消息和调度任务的核心组件。它允许...

    Android应用源码之HandlerLooper1_Android.zip

    这个压缩包“Android应用源码之HandlerLooper1_Android.zip”可能包含了一个示例项目,详细展示了如何在Android应用程序中使用这些组件。 首先,我们来深入理解`Handler`。`Handler`是Android中的一个关键类,主要...

    安卓Android源码——HandlerLooper1.rar

    每个线程都有一个与之关联的`Looper`对象,但默认情况下,只有主线程有`Looper`。`Looper.prepare()`方法用于初始化线程的消息循环,而`Looper.loop()`则会进入这个循环,不断从消息队列中取出待处理的消息并分发给...

    Android应用源码之HandlerLooper2.zip

    `Android应用源码之HandlerLooper2.zip`可能包含了一个示例项目,用于演示如何有效使用这些组件。以下是对这些核心概念的详细说明: 1. **Handler**: `Handler` 是一个用于在特定线程(通常是UI线程)中发送和...

    Android应用源码之HandlerLooper1.zip

    本资料“Android应用源码之HandlerLooper1.zip”应该是包含了一个关于这些组件的详细示例或分析,让我们来深入探讨它们的工作原理。 首先,`Handler`是Android中的一个类,它用于在UI线程中发送和处理消息。当你...

    android的消息处理机制(图+源码分析)——Looper,Handler,Message

    android源码中包含了大量的设计模式, 除此以外, android sdk还精心为我们设计了各种helper类, 对于和我一样渴望水平得到进阶的人来说, 都太值得一读了。 这不, 前几天为了了解android的消息处理机制, 我看 了...

    Android源码与教程

    在Android开发领域,深入理解Android源码是提升技术能力的关键步骤。这个压缩包"Android源码与教程"包含了淘宝上购买的相关教程和一些文档源码,对于开发者来说是一份宝贵的资源。下面,我们将深入探讨Android源码的...

    应用源码之HandlerLooper1.zip

    在Android系统中,`...总之,"应用源码之HandlerLooper1.zip"是一个很好的学习资源,它提供了Android消息处理机制的实际示例,帮助开发者深入理解这一核心组件的内部工作原理,从而提升Android应用开发的专业技能。

    进阶android源码demo

    "进阶Android源码demo"提供了一系列的实践项目,包括游戏和聊天应用,为开发者提供了丰富的学习资源。下面,我们将深入探讨这些知识点,以帮助你更好地理解和应用Android源码。 1. **Android框架理解**:Android...

    应用源码之HandlerLooper2.zip

    本资料"应用源码之HandlerLooper2.zip"显然是针对这一主题进行深入解析的源码学习资源。以下是关于`Handler`、`Looper`和`MessageQueue`的详细知识讲解。 1. **Handler(处理器)**: `Handler`是Android中的一个...

    android Looper

    总之,`Looper`是Android系统中的核心组件之一,它与`Handler`和`Message`共同构建了强大的异步处理机制。理解和熟练运用`Looper`,对于开发高效、流畅的Android应用程序至关重要。通过阅读指定的博客文章,你可以更...

    博客园客户端android源码

    博客园客户端Android源码分析 博客园是一款深受程序员喜爱的在线技术分享平台,其客户端提供了方便的移动阅读体验。分析博客园的Android源码,我们可以深入理解如何构建一个功能完善的移动应用,特别是针对技术社区...

    安卓Android源码——斗地主源码实现.zip

    这份"安卓Android源码——斗地主源码实现.zip"提供的压缩包包含了一个完整的斗地主游戏的源代码实现,其中主要的文件是"Android斗地主[牌桌实现源码].pdf"。这里我们将详细探讨这个项目中的核心知识点。 1. **...

    消息循环 Looper 及其源码解析

    现在来分析一下Looper的源码: - `Looper.prepare()`: 这个方法会初始化Looper和MessageQueue,并将当前线程与Looper关联。它还会设置一个标志,防止在一个线程中多次调用`prepare()`。 - `Looper.loop()`: 这是消息...

    安卓Android源码——四款小游戏源码分析.rar

    这份名为"安卓Android源码——四款小游戏源码分析.rar"的压缩包文件提供了四个不同的小游戏源码,对于想要深入理解Android游戏开发的程序员来说,这是一份宝贵的资源。以下是对这些游戏源码可能涉及的知识点的详细...

    安卓Android源码——四款小游戏源码分析.zip

    本资源“安卓Android源码——四款小游戏源码分析.zip”提供了一次深入理解Android游戏开发的宝贵机会。通过对这四款小游戏的源码进行分析,我们可以学习到许多关键的编程技术和设计模式。 首先,我们要了解Android...

Global site tag (gtag.js) - Google Analytics