Hander,Looper,Message,MessageQueue之间的关系

先简单介绍一下Hander,Looper,Message,MessageQueue之间的关系
Hander:简单来说就是一个消息插值器。
Looper:简单来说就是一个消息接收器。
MessageQueue:简单来说就是一个消息载体
Message:简单来说就是消息载体需要运输的一个
异步线程更新ui线程需要使用Hander去发送消息,我们需要把Hander去实例化在主线程中,去实现handleMessage方法,这样就可以更新ui。
具体原理如下
主线程在ActivityThread里有这样一句话

    Process.setArgV0("<pre-initialized>");
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);`

这句话说明了主线中已经帮我们创建了Looper,我们在看一下perpareMainLooper()

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

再看prepare()方法

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所以在主线中直接创建Hander不会报错,

然后我们看你这些是怎么关联上的,在Hander中的构造方法里会实现这样的方法

 public Handler(Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }

        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;
    }

我们在看myLooper方法

   public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }

从sthreadLocal中去取出Looper,这样我们Hander和ActivityThread就关联上了

接下来看Looper中的轮循

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;

        // 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();
        }
    }

这内容很简单,就是从MessageQueue中去取出Message,这一Looper就关联了上了MessageQueue,MessageQueue就关联上了Message,既然有取就要有存,最后最简单的一步,大家都知道的一步就是Hander去发消息了

handler2.sendEmptyMessage(1);

至此Hander,MessageQueue,Message,Looper就全部关联上。

猜你喜欢

转载自blog.csdn.net/zhujie_/article/details/52440013