Android进程/线程探究Handler,messageQueue,Runnable,looper源码分析

     三者关系:

  

    a.Runnable和Message可以被压入MessageQueue中,形成一个集合。其中一般情况下某种类型的MessageQueue只允许相同类型的object,实际需要先对Runnable进行转换。

     b.Looper循环做某件事情,如果队列为空,则休眠。

     c.Handler为处理事情,对传进来的各种object进行相应的处理。

    总而言之就是Looper不断的去获取MessageQueue中的某个Message,然后交给Handler处理

    1、Handler

        源码路径:frameworks/base/core/java/android/os/Handler.java

        Handler和Thread的关系:

        每个Thread只对应一个Looper;每个Looper只对应一个MessageQueue;每个MessageQueue中有个多个Message;每个Message中最多指定一个Handler来处理事件。

        由此得出Thread和Handler是一对多的关系

    

        Handler主要的作用有两点,一点是处理Message,第二点是将某个Message压入MessageQueue中。

        Looper取出一个Message后,会调用Handler.dispatchMessage进行消息分发,handleMessage处理消息。

        默认情况下的派发流程是:

                message.classback(Runnable对象) 是否为空,不为空的情况下,优先通过callback来解决

                Handler.mCallback是否为空,不为空的情况下,调用mCallback.handleMessage

                如果前两个对象都不存在,则调用Handler.handleMessage

                由此,Handler的扩展子类可以通过重载dispatchMessage或者handleMessage来改变他的默认行为。

        相关的功能函数post和Send都是负责将某个消息压入MessageQueue中;区别在于后者处理的函数参数是Message,post需要先把其他类型额消息转换成Message,再调用send函数执行下一步。

               

        因为调用者提供的是Runnable对象,post需要先将其封装成一个Message,接着通过对应的send函数把它推送到MessageQueue中。

        

public final boolean post(){
  return sendMessageDelayed(getPostMessage(r),0);
}
private static Message getPostMessage(Runnable r){
  Message m = Message.obtain();//Android系统会维护一个全局的Message池,当使用Message时,可以通过obtain直接获得,而不是自行创建。可以减少不必要的资源浪费
  m.callback = r;//将Runnable对象设置为Message的回调函数
  return m;
}

        当准备好Message后,调用sendMessageDelayed来执行下一步。其内部有通过延长时间再发送消息。

public boolean sendMessageAtTime(Message msg,long uptimeMillis){
  MessageQueue queue = mQueue;//Handler对应的消息队列
  if(queue == null){
    //正常情况下,每个Thread都会有一个MessageQueue来承载消息,除非发生了意外queue才会空
    RuntimeException e = new RuntimeException(this+"sendMessageAtTime() called with no mQueue");
    Log.w("Looper",e.getMessage(),e);
    return false;
  }
  return enqueueMessage(queue,msg,uptimeMillis);//将此消息压入MessageQueue
}

        这样就将一条由Runnable组成的Message通过Handler压入了MessageQueue中。

    2、MessageQueue

        源码路径:frameworks/base/core/java/android/os

        具备队列的所有常规操作包括:

        a.新建队列,由其构造函数和本地方法nativeInit组成。

           其中,nativeInit会在本地创建一个NativeMessageQueue对象,然后直接赋给MessageQueue中的成员变量。

        b.元素入队

            final boolean enqueueMessage(Message msg,long when);

        c.元素出队

            final Message next();

        d.删除元素

            final void removeMessages(Handler h,int what,Object object);

            final void removeMessages(Handler h,Runnable r,Object object);

        f.销毁队列

            通过本地函数nativeDestory销毁

    3、Looper

        源码路径:frameworks/base/core/java/android/os

        用于给线程提供一个消息队列(MessageQueue),并且实现循环等待。

        应用程序使用Looper有两种情况:  

            主线程:AndroidThread

            普通线程:LooperThread

            

class LooperThread extends Thread{
  public Handler mHandler;
  public void run() {
    Looper.prepare();
    mHandler = new Handler(){
      public void handleMessage(Message msg){
        //处理消息的地方
      }
    };
    Looper.loop();//进入主循环
  }
}

            以上代码只有三个步骤:

            a.Looper的准备工作(prepare)

            b.创建处理消息的handler

            c.Looper开始运作(loop)

            Looper中有个重要的成员变量

static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

            这是一个静态变量,一旦import了Looper后,sThreadLocal就已经存在并构建完毕。ThreadLocal只是它所在线程的全局变量,意味着每个线程的Looper都是独立的。

        Looper和Handler的关联是通过构造函数,因为Handler内部有许多内部变量需要初始化比如:

final MessageQueue mQueue;
final Looper mLooper;
final Callback mCallback;
public Handler(){
  mLooper = Looper.myLooper();//通过sThreadLocal.get来获取当前线程中的Looper实例
  mQueue = mLooper.mQueue;//mQueue是Looper与Handler之间沟通的桥梁
  mCallback = null;
}
        后续Handler执行Post/Send两个系列的函数时,会将消息投递到mQueue也就是mLooper.mQueue中。一旦Looper处理到这一个消息时,它又会从中调用Handler来进行处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值