基于8.0.0源码
##定义##
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.
个人理解
- Looper的作用是不断的从MessageQueue中取出消息传给宿主Handler来处理. 主线程不需要我们做操作,系统已经做好处理.
- 如果是新建一个线程需要使用Looper的话, 需要先调用prepare()方法来初始化Looper,然后调用loop()方法来开启循环.
方法细节
构造方法
-
我们可以看到构造方法是私有的,就是不允许通过构造来创建.
private Looper(boolean quitAllowed) { //创建MessageQueue队列 mQueue = new MessageQueue(quitAllowed); //得到当前的线程 mThread = Thread.currentThread(); }
-
一个线程只能有一个Looper实例
初始化方法
-
不能通过构造方法来创建对象,那我们看系统提供了哪些方法
-
static void prepare()
//在子线程中使用Looper的时候调用 public static void prepare() { prepare(true); } 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)); }
-
static void prepareMainLooper()
//主线程即UI线程开启的时候系统已经创建了主线程的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以及MessageQueue###
//返回当前工作线程的looper,如果当前线程没有初始化looper则会返回空
public static @Nullable Looper myLooper() {
return sThreadLocal.get();
}
//返回当前线程正在运行的looper创建的MessageQueue,否则会抛出空指针异常
public static @NonNull MessageQueue myQueue() {
return myLooper().mQueue;
}
loop 方法
-
Looper就是通过此方法不停的从MessageQueue中取出Msg,然后再传递给宿主Handler来处理
public static void loop() { //得到当前线程的looper final Looper me = myLooper(); //looper没有初始化,抛出异常 if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } //得到当前线程的MessageQueue final MessageQueue queue = me.mQueue; //得到当前线程的唯一标识 final long ident = Binder.clearCallingIdentity(); for (;;) { //取出队列中消息 Message msg = queue.next(); if (msg == null) { // No message indicates that the message queue is quitting. return; } .... try { //把消息分发给Handler,Handler来处理消磁 msg.target.dispatchMessage(msg); end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis(); } finally { if (traceTag != 0) { Trace.traceEnd(traceTag); } } .... //消息被回收 msg.recycleUnchecked(); }
}