进程中Looper对象的创建与Handler消息处理过程

APP进程被zygote创建后,会进入ActivityThread.java的mian方法.

1、ActivityThread.main

final H mH = new H();

public static void main(String[] args) {
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);//创建Application对象等
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        Looper.loop();
}

private class H extends Handler {

}
复制代码

2、Looper.prepareMainLooper创建Looper、MessageQueue对象

Looper.java
复制代码

为主线程创建Looper对象,并保存在ThreadLocal对象中。

    public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }
复制代码

2.1 prepare(false)

    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));
    }
复制代码

2.2 myLooper()

    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }
复制代码

2.3 new Looper

创建MessageQueue对象,同时mThread为当前进程的主线程。

    private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }
复制代码

2.3 new MessageQueue

MessageQueue.java
复制代码
    MessageQueue(boolean quitAllowed) {
        mQuitAllowed = quitAllowed;
        mPtr = nativeInit();
    }
复制代码

3 返回H

    final Handler getHandler() {
        return mH;
    }
复制代码

4 Looper.loop()

在for循环中不断从MessageQueue获取Message,MessageQueue的next在queue内元素为空时会阻塞当前主线程。

    public static void loop() {
        final Looper me = myLooper();//获取保存在ThreadLocal中的Looper对象
        final MessageQueue queue = me.mQueue;//获取Looper对象中的MessageQueue

        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

            msg.target.dispatchMessage(msg);

            // Make sure that during the course of dispatching the
            // identity of the thread wasn't corrupted.
            final long newIdent = Binder.clearCallingIdentity();

            msg.recycleUnchecked();
        }
    }
复制代码

4.1 MessageQueue.next

nativePollOnce会阻塞主线程。

Message next() {
    for (;;) {
            if (nextPollTimeoutMillis != 0) {
                Binder.flushPendingCommands();
            }

            nativePollOnce(ptr, nextPollTimeoutMillis);//mPtr = nativeInit();MessageQueue构造函数中初始化MessageQueue对象,供nativePollOnce使用。
    }
}
复制代码

4.2

当next遍历出来的消息不为空,调用Handler的dispatchMessage处理消息。

msg.target.dispatchMessage(msg);//target为Handler类型
复制代码

5 Handler

一个进程中只有一个Looper、MessageQueue对象,分别有三种处理消息的方式,Message对象的callback(Runnable ) 不为空时,回调handleCallback处理消息;当mCallback成员属性不为空时,回调interface Callback的handleMessage;以上都不满足时,回调子类的回调handleMessage处理消息。

Handler.java
复制代码
    public Handler(Callback callback, boolean async) {
        mLooper = Looper.myLooper();
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

    public Handler(Looper looper, Callback callback, boolean async) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }
    
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }
复制代码

5.1 Runnable.run

    private static void handleCallback(Message message) {
        message.callback.run();
    }
复制代码

5.2 接口Callback

    public interface Callback {
        public boolean handleMessage(Message msg);
    }
复制代码

5.3 重写handleMessage

    public void handleMessage(Message msg) {
    }
复制代码

6 消息加入队列

    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);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }
复制代码

7 Message

    Handler target;

    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 sendToTarget() {
        target.sendMessage(this);
    }
复制代码

5 H

H继承Handler,处理AMS事件。

final H mH = new H();
复制代码

转载于:https://juejin.im/post/5ca31825e51d45312f0de3cc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值