码迷,mamicode.com
首页 > 移动开发 > 详细

谈谈我对Android中的消息机制的理解之Handler,Looper和MessageQueue的解释

时间:2015-06-20 07:01:24      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:android   handler   message   looper   messagequeue   

Handler的作用是:发送Message和处理Message,handler发送的Message其实就是发送给自己的对象进行处理,所以谁发送就是谁处理,但是这个绝对有意义,以为这样我们就可以通过Handler将消息的处理从一个线程转到另一个线程了,这个Message几经转手之后,处理它的对象虽然是同一个,但是处理它的线程就变了,变成了创建Handler对象的线程,而不是产生Message对象的线程(当然,这个两个线程可能是一个,但是这样使用handler就是第二个目的了),使用handler的第二个目的是可以是一个Message的处理在未来特定的时间发生,就是延迟消息的处理,比如handler的postDelayed()或者sendMessageDelayed()或sendMessageAtTime()方法。


Looper的作用是关联一个MessageQueue,并且对这个MessageQueue进行轮询,调用它的loop()方法。Looper对象的创建需要调用它的prepare()静态方法创建,不能new。哪个线程创建了Looper,哪个线程就负责调用Looper的loop()方法进行Message的轮询。


MessageQueue的作用是维护一个消息队列,提供给Looper进行轮询,Looper中包含了MessageQueue的引用,创建了Looper对象就创建了一个与之对应的MessageQueue对象,这个MessageQueue对象也是本地的message queue,因为创建它的时候调用了native方法。


Handler和Looper和MessageQueue之间的关系:Handler对象中既有Looper对象的引用也有MessageQueue对象的引用,其中MessageQueue是通过它的Looper对象的一个mQueue属性获取的,而Looper的对象是创建Handler的线程创建的(创建Looper对象需要调用它的静态方法prepare()创建,不能直接new出来),所以我们可以说Handler中的MessageQueue是属于创建这个Handler的线程的,而且实际上也是由这个线程通过它创建的Looper对象的loop()方法对这个MessageQueue进行轮询的。


Looper的对象是通过当前创建Handler的线程创建的,并且要保证这个线程要去调用Looper对象的loop()方法进行Message的轮询(在loop()内部会调用一些native的方法完成本地的消息轮询),如果要退出轮询,可以调用Looper对象的quit()方法。UI线程(主线程)已经帮我们做好了这一切,所以,如果我们在主线程中创建Handler,那么就是由主线程自动帮我们去轮询我们的MessageQueue,所以我们在子线程中调用Handler对象的post(),sendMessage(),才能在主线程(UI线程)中处理我们的Message,而且才能在主线程(UI线程)中更新我们的UI。


其实post(),postDelayed(), sendMessage(), sendMessageDelayed() 这四个方法本质都是调用的sendMessageAtTime()这个方法,只是post对runnable对象进行了包装,包装成了Message对象,而这个Message对象的callback就是runnable,最后我们在选择Message处理方法的时候,优先看这个Message对象有没有callback对象,如果有,就调用这个callback对象,然后再看整个handler对象有没有callback对象,如果有,就调用这个callback对象的handleMessage()方法处理Message对象,如果没有则调用handler对象本身的handleMessage方法处理Message,所以Message的处理是有优先级的。


Handler,Looper和MessageQueue的包含关系
Handler包含了Looper,也包含了Looper的MessageQueue;
Looper包含了MessageQueue,


所以Looper属于Handler,由创建Handler的线程创建和使用,MessageQueue属于Looper,通过创建Handler的线程调用Looper的loop()方法进行轮询。


当我们将Handler对象在主线程(UI线程)中创建的时候,Handler对象会关联一个Looper对象,这个Looper对象不是我们创建的,是早就由Activity中的ActivityThread这个类在main函数中创建好的(整个Android应用的入口函数就是这个main函数),如下:


public static void main(String[] args) {
        SamplingProfilerIntegration.start();

        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());

        Security.addProvider(new AndroidKeyStoreProvider());

        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }


从上面的代码我们可以看见Looper对象是通过Looper.prepareMainLooper()来创建的,而调用loop()开始消息的轮询是在最后:Looper.loop()。通过源码我们可以看见loop()内部是一个for(;;){}的死循环,这个就是整个应用程序的main thread loop。我们开发window应用的时候都知道这个应用就是一个大的死循环,称为main thread loop,而Android应用的main thread loop就在这里。这下我们就知道我们的消息究竟是怎样被轮询和处理了的吧!找到主循环,一切都迎刃而解了!


总结:Handler负责发送消息和处理消息;Looper负责接收消息和轮询消息,并且将消息转发给Handler自己,由Handler自己在不同的线程中处理消息;MessageQueue就是一个消息的容器,Looper内部包含了MessageQueue对象的引用,就是通过这个容器(其实就是一个以linked list形式保存Message对象的数据结构),Looper才能完成对消息的轮询(通过loop()方法)。

谈谈我对Android中的消息机制的理解之Handler,Looper和MessageQueue的解释

标签:android   handler   message   looper   messagequeue   

原文地址:http://blog.csdn.net/andyhan_1001/article/details/46570297

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!