android 线程消息深入

    在网上有许多资料对这三者关系的分析,但都比较笼统不够细致入微.

以下是自己深入源码分析其结果.

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;

posted @ 2012-10-25 19:33  编程小爬虫  阅读(251)  评论(0编辑  收藏  举报