Looper Handler MessageQueue,message

  • Activity启动的时候,入口函数main.在ActivityThread
    public static void main(String[] args) {
        SamplingProfilerIntegration.start();
    
        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);
    
        Environment.initForCurrentUser();
    
        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());
    
        Security.addProvider(new AndroidKeyStoreProvider());
    
        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
    
        Process.setArgV0("<pre-initialized>");
    
        Looper.prepareMainLooper();
    
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
    
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
    
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
    
        Looper.loop();
    
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
  • 上述红色部分,就是new了一个mainlooper,

     public static void prepareMainLooper() {
            prepare(false);
            synchronized (Looper.class) {
                if (sMainLooper != null) {
                    throw new IllegalStateException("The main Looper has already been prepared.");
                }
                sMainLooper = myLooper();
            }
        }
    
        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));
        }
    

      所以以后,我们想在子线程new一个主线程的handler,可以直接Handler handler = new Handler(Looper.getMainLooper()); 或者是主线程直接new handler();  ,就可以把子线程要更新UI的直接,就handler.post()

  • ThreadLocal<Looper> 每一个线程都有一个Looper对象,互不影响;相当于给Thread分配了一个内存空间,其他线程不能访问
  • Looper.loop就是不断的从消息队列中取消息,然后交给handler处理,源码如下

      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(); // might block
                if (msg == null) {
                    // No message indicates that the message queue is quitting.
                    return;
                }
    
             ....
    
                final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0;
                final long dispatchEnd;
                try {
                    msg.target.dispatchMessage(msg);
                    dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
                } finally {
                    if (traceTag != 0) {
                        Trace.traceEnd(traceTag);
                    }
                }
               ...
    
                msg.recycleUnchecked();
            }
        }    
    

     其中msg.target,  targeth就是Message对象里的handler对象

  • /**
         * Handle system messages here.
         */
        public void dispatchMessage(Message msg) {
            if (msg.callback != null) {//就是个runnable handler.post(new Runnable())
                handleCallback(msg);
            } else {
                if (mCallback != null) {
                    if (mCallback.handleMessage(msg)) {
                        return;
                    }
                }
                handleMessage(msg);
            }
        }
    
  • 子线程如果想使用handler,要么使用new Handler(HandlerThread.getlooper():,,要么就Looper.prepare();....Looper.loop()
    • Looper.perpare(),就是new一个looper,Looper.loop就是不断的从MessageQueue取消息

 

  • MessageQueue就是一个消息队列,里面是一个链表存放了message

posted on 2019-02-27 11:53  endian11  阅读(105)  评论(0)    收藏  举报

导航