其他分享
首页 > 其他分享> > Handler机制相关流程

Handler机制相关流程

作者:互联网

Handler:发送和接收消息
Looper :轮询循环消息队列,一个线程只有一个Looper
Message:消息的实体
MessageQueue:主要是存储消息和管理消息

创建Looper:

//ActivityThread.java
public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
 		//此处省略代码
        Looper.prepareMainLooper();//初始化Looper和messagQueue
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();//用于循环消息
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
//Looper.java
  public static void prepareMainLooper() {
   	//消息队列不可以quit
       prepare(false);
       synchronized (Looper.class) {
           if (sMainLooper != null) {
               throw new IllegalStateException("The main Looper has already been prepared.");
           }
           sMainLooper = myLooper();
       }
   }
/**
prepare有两个重载的方法,主要是看prepare(boolean quitAllowed) 作用是在创建出MessageQueue时后标识消息队列是否可以被销毁,
但是在主线程中时不会被销毁的
*/
 public static void prepare() {
        prepare(true);
    }

 private static void prepare(boolean quitAllowed) {
      //quitAllowed 
 	  //sThreadLocal.get()不为空表示已经创建出Looper
      if (sThreadLocal.get() != null) {
           throw new RuntimeException("Only one Looper may be created per thread");
           //每个线程只能创建出一个Looper
       }
       //这个地方就是创建出Looper,并且存放到sThreadLocal中
       sThreadLocal.set(new Looper(quitAllowed));
 }

MessageQueue创建以及如何绑定Looper

    private Looper(boolean quitAllowed) {
    	//创建MessageQueue
        mQueue = new MessageQueue(quitAllowed);
        //与当前的线程进行绑定
        mThread = Thread.currentThread();
    }
    MessageQueue(boolean quitAllowed) {
    	//quitAllowed表示是队列是否可以被销毁,主线程的队列不可以被销毁需要传入false
        mQuitAllowed = quitAllowed;
        mPtr = nativeInit();
    }

Looper.looop()

public static void loop() {
        final Looper me = myLooper();//从sThreadLocal中获取到创建出的looper对象
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        final MessageQueue queue = me.mQueue;
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();

        boolean slowDeliveryDetected = false;
        for (;;) {
        	//死循环表示会一直去查询消息
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                // 队列里面没有消息,需要等待MessageQueue发送消息
                return;
            }

            if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
                Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
            }

            final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0;
            final long dispatchEnd;
            try {
                //查询到消息后,然后会去回调到Handler中的dispatchMessage中
                msg.target.dispatchMessage(msg);
                dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
		//后面代码省略......
    }

创建handler

	//常见的Hanlder的创建方式
     Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
        }
    };
    public Handler(@Nullable Callback callback, boolean async) {
   	    //获取Looper,这个是从sThreadLocal中获取到的
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread " + Thread.currentThread()
                        + " that has not called Looper.prepare()");
        }
        //创建出消息队列MessageQueue
        mQueue = mLooper.mQueue;
        //初始化回调
        mCallback = callback;
        mAsynchronous = async;
    }

Looper.myLooper()

Looper.java
	//主要是处理多线程并发的问题
	static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
	
	//获取对于的Looper对象,必须先要调用prepare()方法进行创建
    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }

创建Message

Message.java
       1. Message message = new Message();
       2. Message obtain = Message.obtain();
       
       //使用Message.obtain比直接new出来的Message要好,可以避免多次创建,销毁message对象优化内存和性能的目的
       public static Message obtain() {
       //用来同步,保证线程安全
        synchronized (sPoolSync) {
        	//回收和复用Handler
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }

Message与Handler的绑定
创建Message的时候可以通过Message.obtain(Handler h)这个构造函数去绑定,也可以在Handler enqueueMessage中去绑定,所有发送的Message消息都会调用此方法入队,所以在创建Message的时候可以不去绑定。


private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
            long uptimeMillis) {
        msg.target = this;//绑定
        msg.workSourceUid = ThreadLocalWorkSource.getUid();

        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }

Handler发送消息
Handler发送的消息重载方法很多,但常用的只有两种。sendMessage(Message)方法通过一系列的重载方法调用如下流程:

 //1.入口
 handler.sendMessage(Message);
 //调用到sendMessage
 public final boolean sendMessage(@NonNull Message msg) {
        return sendMessageDelayed(msg, 0);
 }
//2.调用sendMessageDelayed
 public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
 }

 //3.调用到sendMessageAtTime
 public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
 }

//4.调用到enqueueMessage
private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
            long uptimeMillis) {
        msg.target = this;
        msg.workSourceUid = ThreadLocalWorkSource.getUid();

        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
 }

//5.调用到enqueueMessage
//将消息保存在消息队列中,最终又Looper取出,交给Handler的dispatchMessage进行处理
 boolean enqueueMessage(Message msg, long when) {
        if (msg.target == null) {
            throw new IllegalArgumentException("Message must have a target.");
        }
        if (msg.isInUse()) {
            throw new IllegalStateException(msg + " This message is already in use.");
        }

        synchronized (this) {
       		 //表示此消息队列已经被放弃了
            if (mQuitting) {
                IllegalStateException e = new IllegalStateException(
                        msg.target + " sending message to a Handler on a dead thread");
                Log.w(TAG, e.getMessage(), e);
                msg.recycle();
                return false;
            }

            msg.markInUse();
            //延迟时间
            msg.when = when;
            //获取到消息的第一个元素
            Message p = mMessages;
            boolean needWake;
            if (p == null || when == 0 || when < p.when) {
                // New head, wake up the event queue if blocked.
                //如果此队列中头部元素是null(空的队列,一般是第一次),或者此消息不是延时的消息,则此消息需要被立即处理,
                //此时会将这个消息作为新的头部元素,然后判断如果Looper获取消息的线程如果是阻塞状态则唤醒它,让它立刻去拿消息处理
                msg.next = p;
                mMessages = msg;
                needWake = mBlocked;
            } else {
            //如果此消息是延时的消息,则将其添加到队列中,原理就是链表的添加新元素,按照when,也就是延迟的时间来插入的,延迟的时间越长,
            //越靠后,这样就得到一条有序的延时消息链表,取出消息的时候,延迟时间越小的,就被先获取了.
                needWake = mBlocked && p.target == null && msg.isAsynchronous();
                Message prev;
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                    if (needWake && p.isAsynchronous()) {
                        needWake = false;
                    }
                }
                msg.next = p; // invariant: p == prev.next
                prev.next = msg;
            }

            // We can assume mPtr != 0 because mQuitting is false.
            if (needWake) {//唤醒线程
                nativeWake(mPtr);
            }
        }
        return true;
    }
	
    public void dispatchMessage(@NonNull Message msg) {
   		 //callback在Message的构造方法中初始化和使用
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
            	//最终回调到上层执行handlerMessage方法
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

Handler处理消息
在handlerMessage(Message)方法中,我们就可以拿到Message对象,然后进行处理,整个Handler的流程就结束了

    Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
        	//获取Message,进行处理
            super.handleMessage(msg);
        }
    };

总结
Handler的大致流程如上步骤。 从handler.sendMassge发送消息到消息队列MessageQueue,然后调用looper调用到自己loop()函数带动MessageQueue从而去轮询MessageQueue里面的每个Message,当Message达到了可以执行的时间的时候开始执行,执行后会调用Message绑定的Handler来处理消息。

标签:MessageQueue,流程,Handler,Looper,msg,new,Message,机制
来源: https://blog.csdn.net/qq_42989195/article/details/123191045