Android Handler核心类说明

Handler 源码分析

Handler 核心类
核心类说明
Message数据单元,消息对象
MessageQueue数据结构,先进先出,用于存储Message
Handler主线程与子线程的通信媒介,Message的主要处理者
LooperMessageQueue与Handler的通信媒介,从MessageQueue读取Message,分配给Handler处理
Message源码分析

创建方式

//方式一
Message message = new Message();
//方式二,推荐使用,从全局池返回一个新的消息实例。允许我们在许多情况下避免分配新对象。
Message obtain = Message.obtain();

源码分析

public final class Message implements Parcelable {
    //区分消息类型
    public int what;
    //携带int类型变量
    public int arg1;
    public int arg2;
    //携带Object类型变量
    public Object obj;
    //消息执行时间
    long when;
    //携带Bundle数据,和arg1 arg2 obj类似
    Bundle data;
    //发送消息的Handler引用
    Handler target;
    //处理消息的回调
    Runnable callback;
    //Message是单链表结构,next用于保存下一个节点
    Message next;
    //消息池
    private static Message sPool;
    //当前消息称数量
    private static int sPoolSize = 0;
    //消息池最多50个
    private static final int MAX_POOL_SIZE = 50;

    //从消息池获取一个消息,如果消息池是空则新建一个消息
    //避免不要的内存分配
    public static Message obtain() {
        synchronized (sPoolSync) {
            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();
    }
}
MessageQueue源码分析

MessageQueue主要是用于管理Message。

MessageQueue几乎所有方法都有synchronized 关键字,说明这个类做了线程安全处理。

MessageQueue#enqueueMessage()

//将Message插入消息队列中
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;
        }
        //标记这个Message已经被使用
        msg.markInUse();
        msg.when = when;
        //mMessage是一个Message对象
        Message p = mMessages;
        boolean needWake;
        //若队列中没有消息,或该消息立即执行,则放在消息队列的头部
        if (p == null || when == 0 || when < p.when) {
            msg.next = p;
            mMessages = msg;
            needWake = mBlocked;
        } else {
            needWake = mBlocked && p.target == null && msg.isAsynchronous();
            //记录跳出循环前最后一个Message对象
            Message prev;
            //死循环
            //消息队列里有消息,则根据消息发送的时间插入队列中
            for (;;) {
                prev = p;
                //获取链表的下一个                
                p = p.next;
                if (p == null || when < p.when) {
                    //跳出循环
                    break;
                }
                if (needWake && p.isAsynchronous()) {
                    needWake = false;
                }
            }
            //将消息插入合适的位置
            msg.next = p; 
            prev.next = msg;
        }
        if (needWake) {
            nativeWake(mPtr);
        }
    }
    return true;
}

MessageQueue#next()

当消息被插入消息队列中,会被MessageQueue#next()发现,交给Looper处理。

//取出消息
Message next() {  
    //该参数用于判断消息队列中是否有消息
    //-1:一直阻塞不会超时;0:立即返回;>0:最长阻塞,如有程序唤醒立即返回
    int nextPollTimeoutMillis = 0;
    for (;;) {
        if (nextPollTimeoutMillis != 0) {
            Binder.flushPendingCommands();
        }
        //native层,nextPollTimeoutMillis为-1,消息队列处于等待状态
        nativePollOnce(ptr, nextPollTimeoutMillis);

        synchronized (this) {
            final long now = SystemClock.uptimeMillis();
            Message prevMsg = null;
            Message msg = mMessages;
            //从消息队列中取出消息
            if (msg != null) {
                if (now < msg.when) {
                    nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
                } else {
                    //取出消息
                    mBlocked = false;
                    if (prevMsg != null) {
                        prevMsg.next = msg.next;
                    } else {
                        mMessages = msg.next;
                    }
                    msg.next = null;
                    if (DEBUG) Log.v(TAG, "Returning message: " + msg);
                    msg.markInUse();
                    return msg;
                }
            } else {
                //若消息队列中无数据,则设置为-1
                //下次循环时,消息队列处于等待状态
                nextPollTimeoutMillis = -1;
            }
        }
    }
}

MessageQueue#quit()

MessageQueue停止循环,将队列中已存在的所有消息清空。

//退出消息队列
void quit(boolean safe) {
    if (!mQuitAllowed) {
        throw new IllegalStateException("Main thread not allowed to quit.");
    }

    synchronized (this) {
        if (mQuitting) {
            return;
        }
        //标记退出状态
        mQuitting = true;
        if (safe) {
            //清除掉可能还没有被处理的消息
            removeAllFutureMessagesLocked();
        } else {
            //暴力清除,直接清除队列中所有消息
            removeAllMessagesLocked();
        }
        //注销
        nativeWake(mPtr);
    }
}

private void removeAllFutureMessagesLocked() {
    //获取当前时间
    final long now = SystemClock.uptimeMillis();
    //当前消息对象
    Message p = mMessages;
    if (p != null) {
        //若当前消息的处理时间大于当前时间,则被清除
        if (p.when > now) {
            removeAllMessagesLocked();
        } else {
            Message n;
            for (;;) {
                n = p.next;
                if (n == null) {
                    return;
                }
                //若其他消息的处理时间大于当前时间,则停止循环
                if (n.when > now) {
                    break;
                }
                p = n;
            }
            p.next = null;
            do {
                //循环清空消息
                p = n;
                n = p.next;
                p.recycleUnchecked();
            } while (n != null);
        }
    }
}

private void removeAllMessagesLocked() {
    Message p = mMessages;
    while (p != null) {
        Message n = p.next;
        p.recycleUnchecked();
        p = n;
    }
    mMessages = null;
}
Looper源码分析

Looper创建时,会创建一个消息队列(MessageQueue),并将Looper对象保存到ThreadLocal里。

Looper不会一直消耗资源,当Looper的MessageQueue没有消息时,Looper会进入阻塞状态。

public final class Looper {
    //使用ThreadLocal保存当前线程的Looper
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    //主线程Looper
    private static Looper sMainLooper; 
    //消息队列
    final MessageQueue mQueue;
    //当前线程
    final Thread mThread;

    //构造函数
    private Looper(boolean quitAllowed) {
        //创建一个消息队列
        mQueue = new MessageQueue(quitAllowed);
        //获取当前线程
        mThread = Thread.currentThread();
    }

    //创建Looper对象
    public static void prepare() {
        prepare(true);
    }

    //创建Looper对象
    private static void prepare(boolean quitAllowed) {
        //重复调用prepare()会报错,每个线程只能有一个Looper
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        //使用ThreadLocal保存Looper
        sThreadLocal.set(new Looper(quitAllowed));
    }

    //创建主线程的Looper
    public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }           
            sMainLooper = myLooper();
        }
    }

    //开启消息循环
    public static void loop() {
        //获取当前线程的Looper对象
        final Looper me = myLooper();
        //若没有调用Looper.prepare()创建Looper,则会报错
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        //获取MessageQueue对象
        final MessageQueue queue = me.mQueue;
        //死循环
        for (;;) {
            //从消息队列中获取消息
            //可能被阻塞,在MessageQueue#next()进行阻塞,依赖MessageQueue唤醒
            Message msg = queue.next();
            //如果没有新消息就结束消息循环
            if (msg == null) {
                return;
            }
            //分发消息给Handler处理
            msg.target.dispatchMessage(msg);
            //释放资源,消息回收并放入消息池
            msg.recycleUnchecked();
        }
    }

    //退出Looper
    public void quit() {
        //MessageQueue#quit() 消息队列退出
        mQueue.quit(false);
    }
}

ActivityThread#main()

主线程的消息循环在ActivityThread#main()中创建。

public static void main(String[] args) {
    //创建主线程的Looper
    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"));
    }

    //开启主线程的消息循环
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}
Handler源码分析
public class Handler {
    //通过ThreadLocal获取当前线程的Looper
    mLooper = Looper.myLooper();
    if (mLooper == null) {
        //通常在子线程中没有调用Looper.prepare()导致报错
        throw new RuntimeException(
            "Can't create handler inside thread " + Thread.currentThread()
            + " that has not called Looper.prepare()");
    }
    //获取消息队列
    mQueue = mLooper.mQueue;
    //处理Message的回调,优先级高于handleMessage()
    mCallback = callback;
    //是否异步消息
    mAsynchronous = async;

    //发送消息
    public final boolean sendMessage(Message msg) {
        return sendMessageDelayed(msg, 0);
    }

    //发送延迟消息
    public final boolean sendMessageDelayed(Message msg, long delayMillis) {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }

    //发送指定时间消息
    public boolean sendMessageAtTime(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);
    }

    //将消息对象交给消息队列处理
    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        //将当前Handler对象赋值为msg的target属性
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        //MessageQueue将消息插入消息队列中
        return queue.enqueueMessage(msg, uptimeMillis);
    }
    
    //处理消息
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            //若Message的callback不为null,则执行
            handleCallback(msg);
        } else {
            //Handler的callback不为null,则执行
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            //重写的handleMessge方法,用于处理消息
            handleMessage(msg);
        }
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值