美文网首页
Looper,Handl,Message,MessageQueu

Looper,Handl,Message,MessageQueu

作者: 萍水相逢_程序员 | 来源:发表于2018-09-10 18:32 被阅读0次

looper源码分析

public final class Looper{
    
    // sThreadLocal.get() will return null unless you've called prepare().
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    final MessageQueue mQueue;
    final Thread mThread;

    
    private Looper(boolean quitAllowed) {
        //looper 管理MessageQueue
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }
    
    public static void prepare() {
        prepare(true);
    }

    //说明一个线程  只能有一个looper
    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }
    
    //代码有省略
    public static void loop(){
         final Looper me = myLooper();
         final MessageQueue queue = me.mQueue;
         for(;;){
            Message msg = queue.next(); 
            if(msg == null){
                //消息空了挂起
                return;
            }
            
            //looper 从message中取出消息,交给handler处理。 looper
            msg.target.dispatchMessage(msg);
            
            ...
            //释放消息
            msg.recycleUnchecked();
        }      
        
    }
    
    //获取当前线程的looper
    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }
    
    //Quits the looper.
    public void quit() {
        mQueue.quit(false);
    }
    
    //Quits the looper safely.
    public void quitSafely() {
        mQueue.quit(true);
    }
    
}

总结:每个线程只有一个looper,这个looper轮询管理该线程的MessageQueue。

Looper常用方式

class LooperThread extends Thread{
    
    
    public Handler mHandler;
    
    public void run(){
        
        Looper.prepare();
        mHandler = new Handler(){
            
            public void handleMessage(Message msg){
                
            }
        };
        Looper.loop();
    }
}

Handler的设计

Handler源码分析

//回调调用
    public interface Callback {
        public boolean handleMessage(Message msg);
    }
    
    //接收消息方法
    public void handleMessage(Message msg) {
    }
    
    //looper 循环messageQueue后, 出队后的数据通过此方法执行
    //msg.callback 是runable, 这个方法执行的顺序问题,具体使用考虑场景
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                //传入接口回调,会优先拦截
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            //new handler 实现接收消息的方法
            handleMessage(msg);
        }
    }
    
    
    public Handler(Callback callback, boolean async){
        ...
        //此处调用 可以看出初始化Handler前必须先调用 Looper.prepare()
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
        
    }
    
    //obtainMessage 重载方法 获取Messa实例, 运用享元模式设计模式
    public final Message obtainMessage()
    {
        return Message.obtain(this);
    }
    
     public final Message obtainMessage(int what)
    {
        return Message.obtain(this, what);
    }
    ...
    
    //Returns true if the Runnable 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 post(Runnable r)
    {
       //调用getPostMessage得到Message
       return  sendMessageDelayed(getPostMessage(r), 0);
    }
    
    //直接message或者runnable形式,最后都是通过enqueueMessage加入MessageQueue
    public final boolean sendMessage(Message msg)
    {
        return sendMessageDelayed(msg, 0);
    }
    
    //runnable  包装成Message
    private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
    }
    
    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) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        //加入MessageQueue队列
        return queue.enqueueMessage(msg, uptimeMillis);
    }
    
    //重队列移除对应的消息
    public final void removeCallbacks(Runnable r)
    {
        mQueue.removeMessages(this, r, null);
    }
    
    //等相关的移除方法
    public final void removeMessages(int what, Object object) {
        mQueue.removeMessages(this, what, object);
    }

总结: Handler关联单一线程和MessageQueue;处理looper轮询分发的消息,和将消息加入MessageQueue中。

Message的设计分析

用对象池思想,运用享元模式,采用链表形式缓存Message实例,方便快速获取。

Message源码分析

public final class Message implements Parcelable{
    
    // sometimes we store linked lists of these things
    /*package*/ Message next;

    private static final Object sPoolSync = new Object();
    private static Message sPool;
    private static int sPoolSize = 0;

    private static final int MAX_POOL_SIZE = 50;
    
    //存在缓存则从缓存链表获取头, 并做相应的链表指向修改,没有则new一个 
    //obtain重载的的方法 都是如此思想获取
    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();
    }
    
    public void recycle() {
        if (isInUse()) {
            if (gCheckRecycle) {
                throw new IllegalStateException("This message cannot be recycled because it "
                        + "is still in use.");
            }
            return;
        }
        recycleUnchecked();
    }
    
    //释放,缓存个数没到上线则加入缓存池中 
    void recycleUnchecked() {
        // Mark the message as in use while it remains in the recycled object pool.
        // Clear out all other details.
        flags = FLAG_IN_USE;
        what = 0;
        arg1 = 0;
        arg2 = 0;
        obj = null;
        replyTo = null;
        sendingUid = -1;
        when = 0;
        target = null;
        callback = null;
        data = null;

        synchronized (sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) {
                next = sPool;
                sPool = this;
                sPoolSize++;
            }
        }
    }
}

相关文章

网友评论

      本文标题:Looper,Handl,Message,MessageQueu

      本文链接:https://www.haomeiwen.com/subject/dpqegftx.html