7.2 第一步:Looper线程准备阶段

本节分析Looper线程的第一步操作:Looper线程准备阶段。这个阶段由Looper.prepare方法完成,该方法位于frameworks/base/core/java/android/os/Looper.java中,代码如下:


public class Looper{

//定义一个线程局部对象存储Looper对象

static final ThreadLocal<Looper>sThreadLocal=new ThreadLocal<Looper>();

private static Looper sMainLooper;//guarded by Looper.class

final MessageQueue mQueue;

final Thread mThread;

volatile boolean mRun;

private Printer mLogging;

//将当前线程初始化为一个Looper线程,进入线程准备阶段

public static void prepare(){

prepare(true);

}

private static void prepare(boolean quitAllowed){//重载方法

//每个线程只允许有一个Looper实例

if(sThreadLocal.get()!=null){

throw new RuntimeException("Only one Looper may be created per thread");

}

/*创建Looper对象并存入sThreadLocal,这样每个调用

prepare方法的线程将创建本线程唯一的Looper对象/

sThreadLocal.set(new Looper(quitAllowed));

}

public static Looper myLooper(){//用于返回当前线程创建的Looper对象

return sThreadLocal.get();

}


prepare方法会调用其重载方法创建一个Looper对象,并将其存入线程局部变量sThreadLocal中。sThreadLocal是ThreadLocal类型的变量,保证每个线程中都有该Looper对象的独立副本。

创建Looper对象时,会首先判断sThreadLocal线程局部变量中是否已经存在一个Looper对象,如果存在便会抛出运行时异常,因此在当前线程中多次调用prepare方法会导致线程异常退出,所以Looper对象是线程唯一的。

综上所述,prepare方法创建了一个线程独立且唯一的Looper对象,如果要访问这个Looper对象,只需要调用myLooper方法。

创建Looper对象的过程涉及很多步骤,接下来分步分析。

7.2.1 创建Java层的Looper对象

首先分析Java层Looper对象的构造函数,代码如下:


private Looper(boolean quitAllowed){//参数quitAllowed为true

mQueue=new MessageQueue(quitAllowed);

mRun=true;

mThread=Thread.currentThread();

}


Looper在构造函数中创建了MessageQueue对象,并将其存入成员变量mQueue中,然后将mRun赋值为true,表示当前线程处于run状态,最后在成员变量mThread中存储当前线程。

创建Java层Looper对象的同时创建了Java层的MessageQueue对象,接下来分析MessageQueue的创建过程。