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

Android_Handler,Looper,Message深入分析

阅读更多
    在网上有许多资料对这三者关系的分析,但都比较笼统不够细致入微.
以下是自己深入源码分析其结果.
Handler 源码:
public class Handler {
    private static final boolean FIND_POTENTIAL_LEAKS = false;
    private static final String TAG = "Handler";

    public interface Callback {
        public boolean handleMessage(Message msg);
    }
    final MessageQueue mQueue;
    final Looper mLooper;
    final Callback mCallback;
    IMessenger mMessenger;
    /**
     * Subclasses must implement this to receive messages.
     */
    public void handleMessage(Message msg) {
    }
    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;
    }

    /**
     * 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);
        }
    }
    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;
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis)
    {
        boolean sent = false;
        MessageQueue queue = mQueue;
        if (queue != null) {
            msg.target = this;
            sent = queue.enqueueMessage(msg, uptimeMillis);
        }
        else {
            RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
        }
        return sent;
    }

从源码分析可以看出:
handler在无参数的构造方法中调用Looper.myLooper()方法,里面就是从当前线程里面获取一个Looper对象,如果没有则创建.这样对Looper就进行初始化,初始化Looper的同时一并初始化MessageQueue,并且从中得到looper的MessageQueue .可以看出Handler就是Looper和MessageQueue的管理者和调度者.
其中最重要的是:sendMessageAtTime(Message msg, long uptimeMillis)这个方法,当你往Handler中发送Message消息的时候,从代码看出他自己并不去处理Message ,而是交给了MessageQueue.由以下从这段代码来处理:
queue.enqueueMessage(msg, uptimeMillis), 其具体实现要看下面的对
MessageQueue的分析


Looper结构关联的内容:
Looper 源码:
public class Looper {
    private static final boolean DEBUG = false;
    private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;

    // sThreadLocal.get() will return null unless you've called prepare().
    private static final ThreadLocal sThreadLocal = new ThreadLocal();

    final MessageQueue mQueue;
    volatile boolean mRun;
    Thread mThread;
    private Printer mLogging = null;
    private static Looper mMainLooper = null;
   
    public static final void prepare() {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper());
}
public static final void loop() {
        Looper me = myLooper();
        MessageQueue queue = me.mQueue;
        while (true) {
            Message msg = queue.next(); // might block
            if (msg != null) {
                if (msg.target == null) {
                    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);
                msg.recycle();
            }
        }
    }
从源码可以看出Looper 封装的信息:

Looper实质上是对当前线程, ThreadLocal,MessageQueue的封装,也就是负责在多线程之间传递消息的一个循环器.

当你往Handler中添加消息的时候则,里面这个方法: public static final void loop()死循环的方法就会被系统调用,之后的功能代码是:
msg.target.dispatchMessage(msg),则从MessageQueue中得到一个
Message(msg),之后调用Handler的dispatchMessage(msg),这个方法内部实际调用的就是 Handler.handleMessage(msg)方法,这个就是我们在
activity要重写的方法,所以我们就能够得到其他子线程传递的Message了.

Message的源码分析:
public final class Message implements Parcelable {
    public int what;
    public int arg1;
    public int arg2;
    public Object obj;
    public Messenger replyTo;
    long when;
    Bundle data;
    Handler target;    
    Runnable callback;
    Message next;
    private static Object mPoolSync = new Object();
    private static Message mPool;
    private static int mPoolSize = 0;
    private static final int MAX_POOL_SIZE = 10;
   
When: 向Handler发送Message生成的时间
Data: 在Bundler 对象上绑定要线程中传递的数据
Next: 当前Message 对一下个Message 的引用
Handler: 处理当前Message 的Handler对象.
mPool: 通过字面理解可能叫他Message池,但是通过分析应该叫有下一个Message引用的Message链更加适合.
其中Message.obtain(),通过源码分析就是获取断掉Message链关系的第一个Message.
MessageQueue

public class MessageQueue {
    Message mMessages;
    private final ArrayList mIdleHandlers = new ArrayList();
    private boolean mQuiting = false;
    boolean mQuitAllowed = true;
   
    public static interface IdleHandler {
        boolean queueIdle();
}

public final void addIdleHandler(IdleHandler handler) {
     if (handler == null) {
         throw new NullPointerException("Can't add a null IdleHandler");
     }
        synchronized (this) {
            mIdleHandlers.add(handler);
        }
}

final boolean enqueueMessage(Message msg, long when) {
        if (msg.when != 0) {
            throw new AndroidRuntimeException(msg
                    + " This message is already in use.");
        }
        if (msg.target == null && !mQuitAllowed) {
            throw new RuntimeException("Main thread not allowed to quit");
        }
        synchronized (this) {
            if (mQuiting) {
                RuntimeException e = new RuntimeException(
                    msg.target + " sending message to a Handler on a dead thread");
                Log.w("MessageQueue", e.getMessage(), e);
                return false;
            } else if (msg.target == null) {
                mQuiting = true;
            }

            msg.when = when;
            //Log.d("MessageQueue", "Enqueing: " + msg);
            Message p = mMessages;
            if (p == null || when == 0 || when < p.when) {
                msg.next = p;
                mMessages = msg;
                this.notify();
            } else {
                Message prev = null;
                while (p != null && p.when <= when) {
                    prev = p;
                    p = p.next;
                }
                msg.next = prev.next;
                prev.next = msg;
                this.notify();
            }
        }
        return true;
    }
mMessages: 为当前序列的第一个Message, 通过源码分析 MessageQueue并不是对许多Message 之间的关系维护,这样也许可以省去很多事把,而Message 之间的关系
则统统丢给了Message自己去维护,这个可以从对Message源码分析可以理解.

mIdleHandler: 保存的是一系列的handler的集合.

其中final boolean enqueueMessage(Message msg, long when),
这个方法就是上面提到Handler 处理消息时调用到的方法,对她理解了就显
的很重要了,功能代码如下:
msg.when = when;
Message p = mMessages;
if (p == null || when == 0 || when < p.when) {
       msg.next = p;
       mMessages = msg;
       this.notify();
} else {
      Message prev = null;
      while (p != null && p.when <= when) {
               prev = p;
               p = p.next;
           }
       msg.next = prev.next;
       prev.next = msg;
       this.notify();
}

当向MessageQueue中添加消息的时候,判断当前的Message(mMessage)是否为空,
如果为空或者when=0或者when<p.when: 则把要添加的Message(msg)赋给当
前的Message(mMessage),并且将msg.next属性设为空,
如果不为空: 则循环把当前的Message(mMessage)的下一个Message(next)进行遍历,用prev记住当前的message,直到找到prev的下一个Message为空的时候就退出循环,最后将msg接到prev的屁股后面,
即这段代码: prev.next = msg;
分享到:
评论

相关推荐

    Android应用源码之HandlerMessage1_HandlerMessage.zip

    在Android应用开发中,HandlerMessage1_HandlerMessage是一个关键的主题,涉及到Android系统中的消息处理机制,尤其是Handler、Message和Looper的使用。这些组件是Android异步编程的重要组成部分,用于解决UI线程与...

    Android_Handler01-源码.rar

    在Android开发中,Handler、Looper和Message是实现线程间通信的重要组件,尤其在UI更新和异步任务处理上扮演着核心角色。这个源码库可能是为了帮助开发者深入理解这些组件的工作原理,从而更好地进行多线程编程。 1...

    android_os_MessageQueue.rar_android

    在Android操作系统中,MessageQueue是实现线程间通信和异步处理的核心组件。...通过分析`android_os_MessageQueue.cpp`源代码,开发者可以更深入地了解这个过程,从而优化性能或解决与消息处理相关的复杂问题。

    android线程handler、message、looperDEMO

    `Handler`、`Message`和`Looper`是Android系统提供的一个关键机制,用于在不同的线程间进行通信,特别是主线程(UI线程)与工作线程间的交互。下面将详细解释这三个组件以及它们如何协同工作。 1. **Handler...

    Android应用源码之HandlerLooper1_Android.zip

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

    安卓Android源码——HandlerLooper2.rar

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

    Android 之 Looper、MessageQueue、Handler 与消息循环

    本篇文章将深入探讨Android中消息处理的核心组件——Looper、MessageQueue、Handler以及消息循环的工作原理。理解这些概念对于构建响应迅速、用户友好的应用程序至关重要。 #### 二、核心概念 ##### 1. Looper ...

    安卓Android源码——HandlerLooper1.rar

    这个`HandlerLooper1.rar`文件可能包含了对这些概念的深入解析和示例代码。 首先,我们来详细讲解`Handler`。`Handler`是Android中的一个类,它允许开发者在不同的线程中发送和处理消息。通常,我们在主线程(UI...

    Android应用源码之HandlerLooper1.zip

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

    Android应用源码之HandlerLooper2.zip

    综上所述,`Android应用源码之HandlerLooper2.zip`中的示例可能展示了如何有效地使用`Handler`、`Looper`和`MessageQueue`来管理线程通信和异步任务。通过分析和学习这个示例代码,开发者可以更深入地理解Android...

    Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系 - Hongyang -

    【Android异步消息处理机制】深入理解Looper、Handler、Message三者关系 在Android系统中,异步消息处理机制是实现线程间通信和保证UI线程安全的关键组件。它涉及到了三个核心类:Looper、Handler和Message。这篇...

    应用源码之HandlerLooper1.zip

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

    Android应用源码之HandlerMessage3_Android.zip

    在Android应用开发中,Handler、Message以及Looper是三个至关重要的组件,它们构成了Android中的消息处理机制,用于在主线程和子线程之间进行通信。这个压缩包“Android应用源码之HandlerMessage3_Android.zip”显然...

    androidHandler测试的demo

    在“androidHandler测试的demo”中,我们可以预期包含以下内容: 1. 创建自定义`Handler`子类:这个子类可能重写了`handleMessage(Message msg)`方法,根据`msg.what`的值执行不同的操作,比如更新UI元素或执行特定...

    Android利用handler在线程之间传递代码

    Handler是Android中的一个消息处理类,它与Looper和Message紧密配合,形成了一个消息队列。通常,主线程(UI线程)中有一个默认的Looper在后台不断循环地检查Message队列,一旦发现有新消息,就会调用Handler的`...

    安卓Android源码——HandlerMessage3.rar

    这个压缩包"安卓Android源码——HandlerMessage3.rar"很可能包含了关于这三者如何协同工作的示例代码或者详细分析。现在,我们将深入探讨这些概念及其在Android系统中的作用。 `Handler` 是一个用于发送和处理消息...

    Android_memory-leak-debugging.pdf.zip_Android memory le_android_

    - Handler:Message对象未清除,Handler会保持对Looper和Activity的引用,导致Activity无法正常销毁。 - 辅助类:如BroadcastReceiver、ContentObserver等注册后未正确注销,可能导致内存泄漏。 - 自定义View:...

    安卓Android源码——HandlerMessage2.rar

    在安卓(Android)平台上,`Handler`、`Message` 和 `Looper` 是实现线程间通信和异步处理的关键组件。这些概念对于深入理解Android应用的运行机制至关重要。本资源"安卓Android源码——HandlerMessage2.rar"可能...

    android looper分析

    ### Android Looper 分析 #### 一、概述 在 Android 应用开发中,消息处理机制扮演着极其重要的角色。Looper 类与 Handler 和 Message Queue 共同构成了 Android 的消息处理框架,它们之间的协同工作保证了应用...

    Handler、Looper

    在Android系统中,Handler、Looper和Message构成了一个关键的消息处理机制,用于实现UI线程和其他线程之间的通信。本文将从源码的角度深入探讨这个机制,帮助开发者理解其内部工作原理。 首先,我们来理解Handler的...

Global site tag (gtag.js) - Google Analytics