美文网首页
Handler,Looper,Message

Handler,Looper,Message

作者: JackyWu15 | 来源:发表于2019-12-24 15:41 被阅读0次

从《App的启动过程》一篇知道,zygote会fork新进程,然后加载ActivityThread类,并调用其main方法,这里即为应用程序的启动入口。

public final class ActivityThread {

        ......

   //zygote孵化新进程后,加载ActivityThread,并调用main方法
    public static void main(String[] args) {
        ......
       //创建UI线程的Looper,也即主线线程的Looper,每个MessageQueue只会属于一个线程,而 MessageQueue在Looper中
        Looper.prepareMainLooper();
        //生成ActivityThread对象
        ActivityThread thread = new ActivityThread();
        //false表示非系统应用调用,这里是创建Application和Activity,以及Instrumentation的入口
        thread.attach(false);
        //获取Handler
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        ......
        //启动UI线程消息循环
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
}
//创建并Looper,并赋值给sMainLooper引用
    public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }
 //通过ThreadLocal获取Looper,ThreadLocal保证每个线程有一份自己的Looper
    public static Looper myLooper() {
        return sThreadLocal.get();
    }
private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    //创建Looper
    sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
  //消息队列
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}
public final class Looper {
    private static final String TAG = "Looper";

    // sThreadLocal.get() will return null unless you've called prepare().
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    private static Looper sMainLooper;  // guarded by Looper.class

    final MessageQueue mQueue;
    final Thread mThread;
//循环消息队列
public static void loop() {
    //获取当前线程的Looper
    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;
    // Make sure the identity of this thread is that of the local process,
    // and keep track of what that identity token actually is.
    Binder.clearCallingIdentity();
    final long ident = Binder.clearCallingIdentity();

    //死循环获取
    for (;;) {
        //没有消息则阻塞
        Message msg = queue.next(); // might block
        if (msg == null) {
            // No message indicates that the message queue is quitting.
            return;
        }

        // This must be in a local variable, in case a UI event sets the logger
        Printer logging = me.mLogging;
        if (logging != null) {
            logging.println(">>>>> Dispatching to " + msg.target + " " +
                    msg.callback + ": " + msg.what);
        }

        msg.target.dispatchMessage(msg);

        if (logging != null) {
            logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
        }

        // Make sure that during the course of dispatching the
        // identity of the thread wasn't corrupted.
        final long newIdent = Binder.clearCallingIdentity();
        if (ident != newIdent) {
            Log.wtf(TAG, "Thread identity changed from 0x"
                    + Long.toHexString(ident) + " to 0x"
                    + Long.toHexString(newIdent) + " while dispatching to "
                    + msg.target.getClass().getName() + " "
                    + msg.callback + " what=" + msg.what);
        }

        //回收时添加到消息链表中进行复用
        msg.recycleUnchecked();
    }
}


Handler是通过Looper的ThreadLoadcal来获得Looper,进而获得MessageQueue的。Looper创建时保存了当前的线程,用于标记一个线程一个Looper,而当前Looper又会被ThreadLoadcal保存下来

 new Thread( new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                Handler handler = new Handler();
                handler.post( new Runnable() {
                    @Override
                    public void run() {

                    }
                } );
                Looper.loop();
            }
        } ).start();

相关文章

网友评论

      本文标题:Handler,Looper,Message

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