您的位置:首页 > 产品设计 > UI/UE

Handler的源码分析

2012-07-06 01:47 337 查看
原文地址:作者:周伟 (werii.zhou@gmail.com)
http://blog.163.com/android_zhouwei/blog/static/1712422672010818105241892/

 



 

       其实这是我前端时间的研究成果了,放在了我的Msn博客上,但是感觉没人看。所以找到163.com希望和更多人分享。如果刚刚接触Android不久,又刚好想知道这个问题。那么我希望这篇文章能帮助你一丁丁。既然是第一篇文章,所以我还是要先说一下,我也是在2010年8月才进入Android 开发行列的,所以希望多和大家交流交流。好了言归正传吧!

      刚接触Handler,有很多疑惑,不知道原理,心里不是滋味。于是想查查资料什么的,发现大家都是相互抄袭转载,而且没有深度,所以决定自己研究我用rose大致的画了1下Handler的流程(如上图):

     这里简单的说明一下:某个Acitivty的UiThread启动并创建了1个looper,并调用构造函数looper()初始化包括构造MessageQueue等,并循环开始loop()。这时,我们构建了一个Handler对象,并初始化。当我们调用Handler对象发送消息时,其实只是将Msg 压入自己的队列,而这个队列又是冲looper里获得的(详见Handler的构造),这也是他们关联的原因

    疑问:Ui线程的循环?是不是Ui就阻塞了??,也就是Loop()方法的调用应该在研究研究...

      这里要涉及到几个类:Handler,Looper,Message,MessageQueue,我们先简单介绍下:

        当然免不了要上代码。

Looper:ThreadLocal  sThreadLocal;当前线程的副本,获得当前线程的values
                    MessageQueue  mQueue;//消息队列,下面介绍
                    boolean  mRun;//
                    Thread mThread;//线程
                    static Looper mMainLooper
                    public static final void loop() {

                                 Looper me = myLooper();//这个方法是获得当前线程的副本值里,只有Looper,
                                                                     //return (Looper) sThreadLocal.get();

                                MessageQueue queue = me.mQueue;//获得Looper里的MsgQueue

                                while (true) {//无限循环,直到退出

                                    Message msg = queue.next(); // might block

                                        if (msg != null) {

                                        if (msg.target == null) {

                                            // No target is a magic identifier for the quit message.

                                            return;

                                        }

                                        if (me.mLogging!= null) me.mLogging.println(

                                                ">>>>> Dispatching to " + msg.target + " "

                                                + msg.callback + ": " + msg.what

                                                );

                                        msg.target.dispatchMessage(msg);//通过msg的target对象回调dispatchMessage()
                                                                                        //-->也就是HandlerMessage(),是不是有那么多意思了!

                                        if (me.mLogging!= null) me.mLogging.println(

                                                "<<<<< Finished to    " + msg.target + " "

                                                + msg.callback);

                                        msg.recycle();//处理完的消息回收

                                    }

                                }

                            }
                    public static final void prepare() {//这就告诉了我们,1个线程里只能有1个Looper

                                              if (sThreadLocal.get() != null) {

                                                  throw new RuntimeException("Only one Looper may be created per thread");

                                              }

                                              sThreadLocal.set(new Looper());//某个线程就设置好了他的Looper

                           }
                             private Looper() {//构造函数

                                   mQueue = new MessageQueue();//创建1个消息队列

                                   mRun = true;//表示为run

                                   mThread = Thread.currentThread();//线程初始化为本线程

                               }

                             ----------------------------------------------------------------------------------------------------------

                             Handler:的重要成员定义: 

                           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();//调用Looper的静态方法,获得当前线程的Looper;

                                   if (mLooper == null) {

                                       throw new RuntimeException(

                                           "Can't create handler inside thread that has not called Looper.prepare()");

                                   }

                                   mQueue = mLooper.mQueue;

                                   mCallback = null;

                           }

                            Handler发送消息:SendMesasage会调用如下方法:【还有1个方法如出一辙,不与提及】

                             public boolean sendMessageAtTime(Message msg, long uptimeMillis)

                                {

                                    boolean sent = false;

                                    MessageQueue queue = mQueue;//获取自己的消息队列:

                                    if (queue != null) {

                                        msg.target = this; //把msg的目标设为自己,也就是说回调自己的方法HandleMessage();

                                        sent = queue.enqueueMessage(msg, uptimeMillis);//把msg压入队列,该队列来自looper,Looper

                                    }

                                    else {

                                        RuntimeException e = new RuntimeException(

                                            this + " sendMessageAtTime() called with no mQueue");

                                        Log.w("Looper", e.getMessage(), e);

                                    }

                                    return sent;

             

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  null thread android ui 2010 class