美文网首页
2019-08-10-Handler机制之Looper介绍

2019-08-10-Handler机制之Looper介绍

作者: 王元 | 来源:发表于2019-08-15 23:14 被阅读0次

Handler机制之Looper介绍

1,Handler、MessageQueue、Looper三者之间的关系

  • Handler和Looper的创建线程是相同的,而looper的内部还维护了一个MessageQueue的消息队列,该队列是链表实现的
  • Handler通过sendMessage方法发送消息给Looper中对应的MessageQueue
  • Looper通过消息循环获取消息后,会调用对应的消息中的target(target对应的是发消息的Handler)的dispatchMessage()方法来处理消息。

2,Looper的原理-如何与主线程关联的

消息队列(MessageQueue的创建是在Looper中内部创建的,同时Handler消息的发送与处理都是围绕着Looper来进行的

在Android中,App进程是由Zygote fork而创建的,而我们的ActivityThread就是运行在该进程下的主线程中,那么在ActivityThread的main方法中,Looper会通过prepareMainLooper()来创建内部的消息队列(MessageQueue),同时会通过loop()构建消息循环

Looper.prepareMainLooper();

// Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
// It will be in the format "seq=114"
long startSeq = 0;
if (args != null) {
    for (int i = args.length - 1; i >= 0; --i) {
        if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
            startSeq = Long.parseLong(
                    args[i].substring(PROC_START_SEQ_IDENT.length()));
        }
    }
}
ActivityThread thread = new ActivityThread();
thread.attach(false, startSeq);

if (sMainThreadHandler == null) {
    sMainThreadHandler = thread.getHandler();
}

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.prepareMainLooper()方法

//创建主线程的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();
    }
}
//Looper与当前主线程绑定    
//quitAllowed:主线程的必须是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));
}
//获取当前主线程的Looper对象  
public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}

3,Looper的原理-内部创建消息队列

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

如上可以看出,消息队列是在创建looper对象的时候创建的

3,Looper的原理-消息循环

当前Looper对象与主线程关联后,最后一步会调用Looper对象中的loop()方法来开启消息循环

public static void loop() {
    final Looper me = myLooper();
    if (me == null) {
        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
    }
    final MessageQueue queue = me.mQueue;
    ...省略部分代码
    for (;;) {//一直循环去获取消息队列中的消息
        Message msg = queue.next(); //该方法可能堵塞,
        if (msg == null) {
            //如果没有消息,表示当前消息队列已经退出
            return;
        }

    ...省略部分代码
        try {
         //获取消息后,执行发送消息的handler的dispatchMessage方法。
            msg.target.dispatchMessage(msg);
            end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
        } finally {
            if (traceTag != 0) {
                Trace.traceEnd(traceTag);
            }
        }
    ...省略部分代码
        }

        msg.recycleUnchecked();
    }
}

如上所示,流程比较简单,就是looper一直从消息队列中获取消息,然后调用msg.target.dispatchMessage方法分发消息,如果没有消息,则退出循环

参考文章

相关文章

网友评论

      本文标题:2019-08-10-Handler机制之Looper介绍

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