Handler Looper Messagequeue Message 细节以及关系

前两天和朋友看 lunchar模块其中的一个问题, 引发了我还是要写一下这个兴趣,网上太多了
其实写这个并不是单独的为了 将联系 贴代码。 下面的串联解释 和 代码也只不过是顺带的,因为代码中用到 handler 的一个小细节致使 lunchar线程堵塞,可以仔细看下 handler,looper,message,在相互调用的时候,并没有重新开启新线程的代码,所以你们就自己多看看上半页面的 方法解释吧,特别是对 post send 这些方法实质运行在哪个要了解。

对原理和源码特别想了解的,再往下看,其实以前也没有真正的看过源代码,现在现在工作的原因,成天是做些 系统方面的,所以就接触的比较多的,就黏源码了,再简单的东西 我觉得也很重要,也值得学习。

先看下
handler
public class Handler extends Object

A Handler allows you to send and process Message and Runnable objects associated with a thread’s MessageQueue. Each Handler instance is associated with a single thread and that thread’s message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it – from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.Scheduling messages is accomplished with the post(Runnable), postAtTime(Runnable, long), postDelayed(Runnable, long), sendEmptyMessage(int), sendMessage(Message), sendMessageAtTime(Message, long), and sendMessageDelayed(Message, long) methods. The post versions allow you to enqueue Runnable objects to be called by the message queue when they are received; the sendMessage versions allow you to enqueue a Message object containing a bundle of data that will be processed by the Handler’s handleMessage(Message) method (requiring that you implement a subclass of Handler).
When posting or sending to a Handler, you can either allow the item to be processed as soon as the message queue is ready to do so, or specify a delay before it gets processed or absolute time for it to be processed. The latter two allow you to implement timeouts, ticks, and other timing-based behavior.
When a process is created for your application, its main thread is dedicated to running a message queue that takes care of managing the top-level application objects (activities, broadcast receivers, etc) and any windows they create. You can create your own threads, and communicate back with the main application thread through a Handler. This is done by calling the same post or sendMessage methods as before, but from your new thread. The given Runnable or Message will then be scheduled in the Handler’s message queue and processed when appropriate.

当默认创建一个新的Handler实例时, 它会绑定到当前线程和消息的队列中,开始分发数据

     // 它安排消息,用以下方法 因为他绑定在当前主线程  所以以下方法也是
        // post(Runnable) 
        // postAtTime(Runnable,long) 
        // postDelayed(Runnable,long) 
        // sendEmptyMessage(int) 
        // sendMessage(Message); 
        // sendMessageAtTime(Message,long) 
        // sendMessageDelayed(Message,long

1. 以上方法以 post开头的允许你处理Runnable对象
2. 调用Handler的post方法,将要执行的线程对象添加到线程队列当中
此时将会把该线程对象添加到handler对象的线程队列中 ,该Runnable的执行其实并未单独开启线程,而是仍然在当前Activity线程中执行的,
3. Handler只是调用了Runnable对象的run方法。
4. sendMessage()允许你处理Message对象(Message里可以包含数据)
如果想要这个流程一直执行的话,可以在run方法内部执行postDelayed或者post方法,再将该线程对象添加到消息队列中,重复执行。想要线程停止执行,调用Handler对象的removeCallbacks(Runnable r) 方法从线程队列中移除线程对象,使线程停止执行。
5. Handler属于哪个Thread取决于Handler在那个Thread中建立。
6. Handler一定要在主线程实例化吗?
new Handler()和new Handler(Looper.getMainLooper())的区别
如果你不带参数的实例化:Handler handler = new Handler();那么这个会默认用当前线程的 looper要刷新UI,handler要用到主线程的looper。那么在主线程 Handler handler = new Handler();,
如果在其他线程,也要满足这个功能的话,要Handler handler = new Handler(Looper.getMainLooper());
7. Looper.prepare(); Loop.loop();
Handler handler = new Handler();
或者Handler handler = new Handler(Looper.getMainLooper());
若是实例化的时候用Looper.getMainLooper()就表示放到主UI线程去处理。
如果不是的话,因为只有UI线程默认Loop.prepare();Loop.loop();过,其他线程需要手动调用这 两个,否则会报错。

8.HandlerThread,Android 提供了一个线程类 HanderThread 类,HanderThread类继承Thread类,它封装了 Looper 对象,使我们不用关心 Looper 的开启和释放的细节问题HandlerThread 对象中可以通过 getLooper 方法获取一个 Looper 对象引用。

HandlerThread
class for starting a new thread that has a looper. The looper can then be used to create handler classes. Note that start() must still be called.
  HandlerThread 这个类能方便的开启一个包含looper的线程,这个looper也能被用来创建一个handler对象(意思就是把looper以参数形式传递到handler的构造器),
并提示我们注意:在用到HandlerThread 时,同样必须调用start方法。
  

其主要的方法有

  public Looper getLooper ()
   public int getThreadId ()
  public boolean quit ()
  public void run ()
    //创建 thread 其中封装了  looper 的调用
    HandlerThread mHandlerThread =  new HandlerThread("abc");
    mHandlerThread.start();
    //与handler结合
    Handler han = new Handler(mHandlerThread.getLooper());

9.handler callback 的用法(感觉用的不是特别多,就是实现handler的 Callback接口)

        mHandler = new Handler( looper , mCallback );  
        mHandler = new Handler( mCallback ) 

10.伴随着handler ,一般又会拿 handler 去和 asynctask 进行比较,其实说简单一点就是asynctask 将我们平常写的 thread 和 handler 组合到了一起,封装起来使用更加的方便了

    asynctask 可以使用我们自己的线程池 
        Executor exec = new ThreadPoolExecutor(15, 200, 10,  
        TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());  
        new DownloadTask().executeOnExecutor(exec);  

handler类源码
android/frameworks/base/core/java/android/os

package android.os;
import android.util.Log;
import android.util.Printer;
import java.lang.reflect.Modifier;
public class Handler {
    private static final boolean FIND_POTENTIAL_LEAKS = false;
    private static final String TAG = "Handler";

    public interface Callback {
        public boolean handleMessage(Message msg);
    }
    public void handleMessage(Message msg) {
    }

    /**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

    // handler的一些构造方法
    public Handler() {
        this(null, false);
    }

    public Handler(Callback callback) {
        this(callback, false);
    }
    public Handler(Looper looper) {
        this(looper, null, false);
    }
    public Handler(Looper looper, Callback callback) {
        this(looper, callback, false);
    }  
    public Handler(boolean async) {
        this(null, async);
    }

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


    public Handler(Looper looper, Callback callback, boolean async) {
        mLooper = looper;       // 获取looper
        mQueue = looper.mQueue; // 获取queue
        mCallback = callback;
        mAsynchronous = async;
    }

    public String getMessageName(Message message) {
        if (message.callback != null) {
            return message.callback.getClass().getName();
        }
        return "0x" + Integer.toHexString(message.what);
    }
    public final Message obtainMessage()
    {
        return Message.obtain(this);
    }
    public final Message obtainMessage(int what)
    {
        return Message.obtain(this, what);
    }
    public final Message obtainMessage(int what, Object obj)
    {
        return Message.obtain(this, what, obj);
    }
    public final Message obtainMessage(int what, int arg1, int arg2)
    {
        return Message.obtain(this, what, arg1, arg2);
    }
    public final Message obtainMessage(int what, int arg1, int arg2, Object obj)
    {
        return Message.obtain(this, what, arg1, arg2, obj);
    }


    public final boolean post(Runnable r)
    {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }

    public final boolean postAtTime(Runnable r, long uptimeMillis)
    {
        return sendMessageAtTime(getPostMessage(r), uptimeMillis);
    }

    public final boolean postAtTime(Runnable r, Object token, long uptimeMillis)
    {
        return sendMessageAtTime(getPostMessage(r, token), uptimeMillis);
    }

    public final boolean postDelayed(Runnable r, long delayMillis)
    {
        return sendMessageDelayed(getPostMessage(r), delayMillis);
    }

    public final boolean postAtFrontOfQueue(Runnable r)
    {
        return sendMessageAtFrontOfQueue(getPostMessage(r));
    }

    public final boolean runWithScissors(final Runnable r, long timeout) {
        if (r == null) {
            throw new IllegalArgumentException("runnable must not be null");
        }
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout must be non-negative");
        }

        if (Looper.myLooper() == mLooper) {
            r.run();
            return true;
        }

        BlockingRunnable br = new BlockingRunnable(r);
        return br.postAndWait(this, timeout);
    }

    public final void removeCallbacks(Runnable r)
    {
        mQueue.removeMessages(this, r, null);
    }


    public final void removeCallbacks(Runnable r, Object token)
    {
        mQueue.removeMessages(this, r, token);
    }

    //send类型的方法
    public final boolean sendMessage(Message msg)
    {
        return sendMessageDelayed(msg, 0);
    }
    public final boolean sendEmptyMessage(int what)
    {
        return sendEmptyMessageDelayed(what, 0);
    }
    public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
        Message msg = Message.obtain();
        msg.what = what;
        return sendMessageDelayed(msg, delayMillis);
    }
    public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
        Message msg = Message.obtain();
        msg.what = what;
        return sendMessageAtTime(msg, uptimeMillis);
    }
    public final boolean sendMessageDelayed(Message msg, long delayMillis)
    {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }

    //最终调用的是  sendMessageAtTime  在这里就可以看到  handler 和 MessageQueue 是怎么交互的了
    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);
    }
    // 在这里将 Message对象 塞入了 queue
    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        //并且返回boolean 告诉你成功没
        return queue.enqueueMessage(msg, uptimeMillis);
    }

    public final boolean sendMessageAtFrontOfQueue(Message msg) {
        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, 0);
    }


    //remove 方法
    public final void removeMessages(int what) {
        mQueue.removeMessages(this, what, null);
    }
    public final void removeMessages(int what, Object object) {
        mQueue.removeMessages(this, what, object);
    }
    public final void removeCallbacksAndMessages(Object token) {
        mQueue.removeCallbacksAndMessages(this, token);
    }



    public final boolean hasMessages(int what) {
        return mQueue.hasMessages(this, what, null);
    }
    public final boolean hasMessages(int what, Object object) {
        return mQueue.hasMessages(this, what, object);
    }


    public final boolean hasCallbacks(Runnable r) {
        return mQueue.hasMessages(this, r, null);
    }
    public final Looper getLooper() {
        return mLooper;
    }

    public final void dump(Printer pw, String prefix) {
        pw.println(prefix + this + " @ " + SystemClock.uptimeMillis());
        if (mLooper == null) {
            pw.println(prefix + "looper uninitialized");
        } else {
            mLooper.dump(pw, prefix + "  ");
        }
    }

    @Override
    public String toString() {
        return "Handler (" + getClass().getName() + ") {"
        + Integer.toHexString(System.identityHashCode(this))
        + "}";
    }

    final IMessenger getIMessenger() {
        synchronized (mQueue) {
            if (mMessenger != null) {
                return mMessenger;
            }
            mMessenger = new MessengerImpl();
            return mMessenger;
        }
    }

    private final class MessengerImpl extends IMessenger.Stub {
        public void send(Message msg) {
            msg.sendingUid = Binder.getCallingUid();
            Handler.this.sendMessage(msg);
        }
    }


    private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
    }
    private static Message getPostMessage(Runnable r, Object token) {
        Message m = Message.obtain();
        m.obj = token;
        m.callback = r;
        return m;
    }

    private static void handleCallback(Message message) {
        message.callback.run();
    }

    final MessageQueue mQueue;
    final Looper mLooper;
    final Callback mCallback;
    final boolean mAsynchronous;
    IMessenger mMessenger;

    private static final class BlockingRunnable implements Runnable {
        private final Runnable mTask;
        private boolean mDone;

        public BlockingRunnable(Runnable task) {
            mTask = task;
        }
        @Override
        public void run() {
            try {
                mTask.run();
            } finally {
                synchronized (this) {
                    mDone = true;
                    notifyAll();
                }
            }
        }

        public boolean postAndWait(Handler handler, long timeout) {
            if (!handler.post(this)) {
                return false;
            }
            synchronized (this) {
                if (timeout > 0) {
                    final long expirationTime = SystemClock.uptimeMillis() + timeout;
                    while (!mDone) {
                        long delay = expirationTime - SystemClock.uptimeMillis();
                        if (delay <= 0) {
                            return false; // timeout
                        }
                        try {
                            wait(delay);
                        } catch (InterruptedException ex) {
                        }
                    }
                } else {
                    while (!mDone) {
                        try {
                            wait();
                        } catch (InterruptedException ex) {
                        }
                    }
                }
            }
            return true;
        }
    }
}

重要:handler的一系列send方法,post方法主要的任务就是把Message对象的添加到MessageQueue中,比如:handler.sendMessage()–>handler.sendMessageDelayed()–>handler.sendMessageAtTime()–>msg.target = this;queue.enqueueMessage==>把msg添加到消息队列中,看下面messagequeue 源码

messagequeue 源码

boolean enqueueMessage(Message msg, long when) {
        if (msg.target == null) {
            throw new IllegalArgumentException("Message must have a target.");
        }
        if (msg.isInUse()) {
            throw new IllegalStateException(msg + " This message is already in use.");
        }

        synchronized (this) {
            if (mQuitting) {
                IllegalStateException e = new IllegalStateException(
                        msg.target + " sending message to a Handler on a dead thread");
                Log.w(TAG, e.getMessage(), e);
                msg.recycle();
                return false;
            }

            msg.markInUse();
            msg.when = when;
            Message p = mMessages;
            boolean needWake;
            if (p == null || when == 0 || when < p.when) {
                // New head, wake up the event queue if blocked.
                msg.next = p;
                mMessages = msg;
                needWake = mBlocked;
            } else {
                // Inserted within the middle of the queue.  Usually we don't have to wake
                // up the event queue unless there is a barrier at the head of the queue
                // and the message is the earliest asynchronous message in the queue.
                needWake = mBlocked && p.target == null && msg.isAsynchronous();
                Message prev;
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                    if (needWake && p.isAsynchronous()) {
                        needWake = false;
                    }
                }
                msg.next = p; // invariant: p == prev.next
                prev.next = msg;
            }

            // We can assume mPtr != 0 because mQuitting is false.
            if (needWake) {
                nativeWake(mPtr);
            }
        }
        return true;
    }

看清楚 messagequeue是怎么放 message的, message.next 放入 下一个

public final class Message implements Parcelable {
         public int what;
         int flags;
         long when;
         //传递简单数据
         public int arg1;
         public int arg2;
         //传递较复杂数据 对象
         public Object obj;
         Bundle data;
         //处理消息的目标Handler
         Handler target;   
         //消息派发时 执行的Runnable对象
         Runnable callback;  
         //使消息形成链表
         Message next;
         //建立一个消息pool,回收msg,以避免重复创建节约开销
         private static Message sPool;
         private static int sPoolSize = 0;
         private static final int MAX_POOL_SIZE = 10;
  }

handler对象管理的Looper对象是线程安全的,不管是加入消息到消息队列和从队列读出消息都是有同步对象保护的(看代码)

Looper 类源码
看呀取的代码, next()

package android.os;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.util.Log;
import android.util.Printer;

/**
  * Class used to run a message loop for a thread.  Threads by default do
  * not have a message loop associated with them; to create one, call
  * {@link #prepare} in the thread that is to run the loop, and then
  * {@link #loop} to have it process messages until the loop is stopped.
  * <p>Most interaction with a message loop is through the
  * {@link Handler} class.
  * <p>This is a typical example of the implementation of a Looper thread,
  * using the separation of {@link #prepare} and {@link #loop} to create an
  * initial Handler to communicate with the Looper.
  * <pre>
  *  class LooperThread extends Thread {
  *      public Handler mHandler;
  *
  *      public void run() {
  *          Looper.prepare();
  *
  *          mHandler = new Handler() {
  *              public void handleMessage(Message msg) {
  *                  // process incoming messages here
  *              }
  *          };
  *
  *          Looper.loop();
  *      }
  *  }</pre>
  */

//上面的注释中有个 代码, 是google写的例子,告诉你,怎么在普通的线程中加入 looper
//Looper 在源码中的代码
public final class Looper {
    /*
     * API Implementation Note:
     *
     * This class contains the code required to set up and manage an event loop
     * based on MessageQueue.  APIs that affect the state of the queue should be
     * defined on MessageQueue or Handler rather than on Looper itself.  For example,
     * idle handlers and sync barriers are defined on the queue whereas preparing the
     * thread, looping, and quitting are defined on the looper.
     */

    private static final String TAG = "Looper";
    // sThreadLocal.get() will return null unless you've called prepare().

    //这个东西也挺重要的 存放looper对象 ,除非你调用 prepare()方法, 不然他就会返回一个null对象
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    private static Looper sMainLooper;  // guarded by Looper.class

    final MessageQueue mQueue;
    final Thread mThread;

    private Printer mLogging;

     /** Initialize the current thread as a looper.
      * This gives you a chance to create handlers that then reference
      * this looper, before actually starting the loop. Be sure to call
      * {@link #loop()} after calling this method, and end it by calling
      * {@link #quit()}.
      */
    public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {

        // 去ThreadLocal中获取 looper 看是不是为null
        if (sThreadLocal.get() != null) {
            //不为null则抛出异常
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        //这里去创建一个 looper对象,并塞入ThreadLocal中
        sThreadLocal.set(new Looper(quitAllowed));
    }

    /**
     * Initialize the current thread as a looper, marking it as an
     * application's main looper. The main looper for your application
     * is created by the Android environment, so you should never need
     * to call this function yourself.  See also: {@link #prepare()}
     */
     //不需要你自己调用 
    public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }

    /**
     * Returns the application's main looper, which lives in the main thread of the application.
     */
    // 返回主线程的 looper
    public static Looper getMainLooper() {
        synchronized (Looper.class) {
            return sMainLooper;
        }
    }

    /**
     * Run the message queue in this thread. Be sure to call
     * {@link #quit()} to end the loop.
     */

    // 运行消息队列在这个线程,请确定调用 quit() 去结束这个 loop

    // 这个就是平常会调用的  Looper.loop()方法了
    public static void loop() {
        // 获取ThreadLocal 中的 looper对象
        final Looper me = myLooper();
        if (me == null) {
            //为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();

        //老版的代码这里使用的是 while(true) ,其实效果是一样的这里的 for (;;)也是执行死循环
        for (;;) {

            //这就是核心了,每次 next() 取出来下一个  Message 对象然后进行处理
            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);
            }

            //在这里去 交给  handler 去处理
            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();
        }
    }

    /**
     * Return the Looper object associated with the current thread.  Returns
     * null if the calling thread is not associated with a Looper.
     */
    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }

    /**
     * Return the {@link MessageQueue} object associated with the current
     * thread.  This must be called from a thread running a Looper, or a
     * NullPointerException will be thrown.
     */
    public static @NonNull MessageQueue myQueue() {
        return myLooper().mQueue;
    }


    //是内部调用的, 在 loop()方法中
    private Looper(boolean quitAllowed) {
        //创建looper时, 创建 MessageQueue()
        mQueue = new MessageQueue(quitAllowed);
        //获取当前 线程 thread
        mThread = Thread.currentThread();
    }

    /**
     * Returns true if the current thread is this looper's thread.
     */
    public boolean isCurrentThread() {
        return Thread.currentThread() == mThread;
    }


    public void setMessageLogging(@Nullable Printer printer) {
        mLogging = printer;
    }


    public void quit() {
        mQueue.quit(false);
    }

上面的msg.target.dispatchMessage(msg) 进入到了 Message.java 中如下的方法,就这样,handler message looper messagequeue 串联起来了

   /**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
        //有没有callback 的回调对象呀
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
           //没有就交给 handlerMessage 处理消息啦
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

Looper,它是用了收发消息并管理消息队列的,它的构造器是私有的,它的实例化需要通过 loop.prepare(),即初始化当前线程为looper,所以我们说,如果用的不是 HandlerThread,而是一个普通的线程,那么如果此时又需要用到looper,那么必须在run方法的第一行写loop.prepare();
Looper源码顶端是有例子的
MessageQueue是在Looper的私有构造函数Looper()中实例化的;
looper.loop实际上就是一个while(true)的死循环,MessageQueue是Looper保留的一份引用,通过它的next()[序列1]获取 MessageQueue中的下一个要处理的消息,这个过程中如果没有相应的消息,执行它的线程会用this.wait()释放它所拥有的MessageQueue的对象锁而等待。

重要:一个Message经由Handler的发送,MessageQueue的塞入,Looper从队列MessageQueue中取出,再次到 Handler的handlerMessage方法中

为什么要说ActivityThread ?

普通创建的线程是没有 looper的, 那为啥 Handler han = new Handler(){}; 就默认有looper类,能更新UI界面, 其实这都在Activity创建时, 在ActivityThread 中给你搞定了的,根本不需要你去创建而已。简单的就可以看到 ActivityThread 中已经进行了处理

public final class ActivityThread {
.......
    final ApplicationThread mAppThread = new ApplicationThread();
    //这里==================
    final Looper mLooper = Looper.myLooper();
    final H mH = new H();
.......
private final class H extends Handler {
.......
}
.......
 public static final void main(String[] args) {
        SamplingProfilerIntegration.start();
        Process.setArgV0("<pre-initialized>");
        Looper.prepareMainLooper();
        if (sMainThreadHandler == null) {
            sMainThreadHandler = new Handler();
        }
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (false) {

            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
           //这里=================
        Looper.loop();
        if (Process.supportsProcesses()) {
            throw new RuntimeException("Main thread loop unexpectedly exited");
        }
        thread.detach();
        String name = (thread.mInitialApplication != null)
            ? thread.mInitialApplication.getPackageName()
        Slog.i(TAG, "Main thread of " + name + " is now exiting");
    }

最最后,说去 主线程的 Looper 这个也要说一下, 因为 UI线程就是主线程, 已经让ActivityThread创建好了,,所以就可以直接获取
源码中有这么一句

Looper.prepareMainLooper();

获取 主线程 Looper

Android MainLooper的获取原理分析

getMainLooper()
Looper myLooper()

private static Looper sMainLooper;

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

public static Looper getMainLooper() {
synchronized (Looper.class) {
return 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();
}
}

猜你喜欢

转载自blog.csdn.net/kongbaidepao/article/details/52294214
今日推荐