Handler 的执行原理----底层代码


        Handler:源代码涉及的5各类:

Handler:
Manager:
Managerqueue;  消息队列
Looper:-----loop() 
HandlerThread----如果要建立自己的消息机制分发必须写一个类作为HandlerThread的孩子存在;    run方法

Looper.loop();主线程while(true) ?  分发消息机制  :
ANR: 不能占用主线过长时间因为占用过长时间就会让主线程不能分发消息机制 了;


Handler消息机制的执行过程: android的底层源码执行过程:
sendMessage发送一个消息:
   /**
     * Pushes a message onto the end of the message queue after all pending messages
     * before the current time. It will be received in {@link #handleMessage},
     * in the thread attached to this handler.
     *
     * @return Returns true if the message was successfully placed in to the
     * message queue. Returns false on failure, usually because the
     * looper processing the message queue is exiting.
     */
    public final boolean sendMessage(Message msg)
    {
        return sendMessageDelayed(msg, 0);
    }

然后返回一个带有当前系统时间的: return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
 

   /**
     * Enqueue a message into the message queue after all pending messages
     * before (current time + delayMillis). You will receive it in
     * {@link #handleMessage}, in the thread attached to this handler.
     *
     * @return Returns true if the message was successfully placed in to the
     * message queue. Returns false on failure, usually because the
     * looper processing the message queue is exiting. Note that a
     * result of true does not mean the message will be processed -- if
     * the looper is quit before the delivery time of the message
     * occurs then the message will be dropped.
     */
    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }

之后在走到这里:拿到一个消息队列: MessageQueue queue = mQueue;  
如果没有拿到这个消息队列就会报异常说没有这个消息队列 : " sendMessageAtTime() called with no mQueue") 
 
  * @param uptimeMillis The absolute time at which the message should be
     * delivered, using the
     * {@link android.os.SystemClock#uptimeMillis} time-base.
     *
     * @return Returns true if the message was successfully placed in to the
     * message queue. Returns false on failure, usually because the
     * looper processing the message queue is exiting. Note that a
     * result of true does not mean the message will be processed -- if
     * the looper is quit before the delivery time of the message
     * occurs then the message will be dropped.
     */
    public boolean sendMessageAtTime(Message msg, long uptimeMillis)
    {
        boolean sent = false;
        MessageQueue queue = mQueue;   //拿到一个消息队列
        if (queue != null) {
            msg.target = this;
            sent = queue.enqueueMessage(msg, uptimeMillis);
        }
        else {
                //没有拿到消息队列就会报异常
            RuntimeException e = new RuntimeException(
                this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
        }
        return sent;
    }

MessageQueue 类中的消息队列:

 final boolean  enqueueMessage(Message msg, long when) {
        if (msg.when != 0) {    
            throw new AndroidRuntimeException(msg
                    + " This message is already in use.");
        }
        if (msg.target == null && !mQuitAllowed) {   //msg.when 必须带有一个否则就抛异常
            throw new RuntimeException("Main thread not allowed to quit");
        }
        final boolean needWake;
        synchronized (this) {
             if (mQuiting) {    
                RuntimeException e = new RuntimeException(
                    msg.target + " sending message to a Handler on a dead thread");
                Log.w("MessageQueue", e.getMessage(), e);
                return false;
            } else if (msg.target == null) {
                mQuiting = true;
            }
            msg.when = when;
            //Log.d("MessageQueue", "Enqueing: " + msg);
            Message p = mMessages;
            if (p == null || when == 0 || when < p.when) {    //通过按时间来对其每一个消息进行排序,
                msg.next = p;
                mMessages = msg;
                needWake = mBlocked; // new head, might need to wake up
            } else {
                Message prev = null;
                while (p != null && p.when <= when) {
                    prev = p;
                    p = p.next;
                }
                msg.next = prev.next;
                prev.next = msg;
                needWake = false; // still waiting on head, no need to wake up
            }
        }
        if (needWake) {
            nativeWake(mPtr);
        }
        return true;
    }

msg.targe=this;
问题: ---我创建了10个handler 同时在发送message ,且Message为什么没有发错:
我会给每一个handle指定一个target,通过这个来指定那个谁来处理这个handle;谁调用这个handler就将这个handler存入这个队列集合中:queue.enqueueMessage(msg, uptimeMillis);
:如果不考虑时间就按先进先出的顺序执行 ,如果有时间就按时间的顺序进行排序      

Looper类中 :在这个消息队列中有一个loop的方法中有着这个对列消息的信息:这里是一个死循环:  while (true) {
 在一直的查看是否有消息要发送没有就会在这里可能阻塞线程中等着

 /**
     * Run the message queue in this thread. Be sure to call
     * {@link #quit()} to end the loop.
     */
    public static final void loop() {
        Looper me = myLooper();
        MessageQueue queue = me.mQueue;
        while (true) {
            Message msg = queue.next(); // might block
            //if (!me.mRun) {
            // break;
            //}
            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);
                if (me.mLogging!= null) me.mLogging.println(
                        "<<<<< Finished to " + msg.target + " "
                        + msg.callback);
                msg.recycle();
            }
        }
    }




AsyncTask:
在大量的使用线程访问网路的时候就不能使用new Thread来创建线程了:这样会大量的浪费资源;因此就可以使用
AsyncTask来实现.在底层使用了线程池每次都是在使用同一个线程;

android问什么启动会比较慢:
因为在启动是加载了两千个类且使用了反射来获取类的信息

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值