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

Android学习笔记之消息机制

时间:2016-08-06 17:36:31      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:

  Android的消息机制主要是指Handler的运行机制以及Handler所附带的MessageQueue和Looper的工作过程。 

  1.为什么要使用Handler?

         Android规定访问UI只能在主线程中进行,如果在子线程中访问UI,则会抛出异常。同时Android建议不能在主线程中进行耗时的操作,不然会导致程序无法响应即ANR。因此耗时的工作只能交给子线程去做,而子线程却不能直接访问UI,为了解决这个矛盾,Android提供了Handler。Handler的主要作用是将某个任务切换到某个指定的线程中去执行。例如,我们在主线程中创建Handler,在子线程执行完耗时任务后,就可以通过Handler将更新UI的操作切换到主线程中去执行。

  2.为什么系统不允许在子线程中访问UI?

        因为Android的UI控件不是线程安全的,如果在多线程中并发访问可能会导致UI控件处于不可预期的状态。

  3.Handler与MessageQueue,Looper

        Android的消息机制主要是指Handler的运行机制,Handler的运行需要消息队列(MessageQueue)和消息循环(Looper)的支撑。

       消息队列的内部存储结构并不是真正的队列,而是单链表。消息队列只是一个消息的存储单元,不能处理消息,而Looper就是来处理消息的。Looper会无限循环的去查看是否有消息,如果有,就处理,否则一直等待。

     Handler创建时会采用当前线程的Looper来构造消息循环系统,如果当前线程没有Looper,则会报错(有的时候,也可以通过构造函数指定一个Looper)。这个当前线程的Looper是通过ThreadLocal来获取的。ThreadLocal并不是线程,它是线程内部的一个数据存储类,通过它可以在指定线性中存储数据和获取数据。

  4.MessageQueue工作原理

         MessageQueue主要包含两个操作:插入和读取,分别对应enqueueMessage和next两个方法。enQueueMessage是往消息队列中插入一条消息,而next是从消息队列中取出一条消息并将其从消息队列中删除。前面说过,消息队列的内部实现是iyge单链表,它在插入和删除上比较有优势。

        这里注意,next方法是一个无限循环的方法,如果消息队列中没有消息,那么next方法会一直阻塞,当有新消息到来时,它会返回这条消息并将其从单链表中删除。 

  5.Looper的工作原理

  (1)Looper会一直不停的从MessageQueue中查看是否有消息,如果有,则会立刻处理,否则就一直阻塞。

     为当前信线程创建Looper的方法如下:

new Thead("Thread1"){

  @override
   public void run()
  {
    Looper.prepare();
    Handler handler=new Handler();
    Looper.loop();
  }
}

       注意,只有调用了Looper的loop方法后,消息循环系统才真正起作用。

         loop方法会调用MessageQueue的next方法来获取消息,当没有消息时,next方法会阻塞,导致loop方法也会阻塞。Looper获得消息后,调用Handler对象的dispatchMessage方法,这个dispatchMessage方法是在创建Handler时所使用的Looper中执行的,这样就就将代码逻辑切换到指定的线程中去了。

         loop方法是一个死循环,唯一跳出循环的方式是MessageQueue的next方法返回null。当Looper的quit方法被调用时,它会调用MessageQueue的quit或者quitSafely方法来通知消息队列退出,当消息队列被标记为退出状态时,其next方法就会返回null。

    (2)Looper也可以退出,主要的方法是quit和quitSafely。前者会直接退出Looper,而后者只是设定一个标记,然后把消息队列中的已有消息处理完毕后才安全退出。Looper退出以后,Handler就无法再顺利发送消息了,其send方法会返回false。

    (3)在子线程中创建Looper后,当所有事情完成以后应该调用quit方法来终止消息循环,否则这个子线程会一直处于等待状态

  6.Handler的工作原理

        Handler的主要工作是发送和接收消息。消息的发送通过post的方法和send的方法实现,post的方法最终是通过send的方法实现的。

        Handler发送消息仅仅是向消息队列中插入一条消息,然后MessageQueue的next方法将消息给Looper处理,最终Looper将消息交给Handler处理,即Handler的dispatchMessage方法被调用。

public void dispatchMessage(Message msg){
if(msg.callback!=null)
{
handleCallback(msg);
}
else
{
if(mCallback!=null)
{

if(mCallback.handleMessage(msg))
{
return;
               }
}
handleMessage(msg);
}
}

     这里msg.callback对象其实就是一个Runnable对象,就是Handler的post方法所传递的Runnable参数

     mCallback对应的类实现的是Callback接口。当我们不想派生Handler的子类并重写其handleMessage方法时,可以通过Callback来实现。

 

Android学习笔记之消息机制

标签:

原文地址:http://www.cnblogs.com/njust-ycc/p/5734749.html

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