Looper几个方法解析

在ActivityThread#main()方法中,有调用Looper.prepareMainLooper()Looper.loop(),平时也经常使用Looper.prepare()Looper.myLooper()这些方法。我们仔细看看这些方法里面到底做了什么。

prepareMainLooper()

    private static Looper sMainLooper; 
    
    public static void prepareMainLooper() {
    	//因为是主线程,所以不允许退出
    	//生成不允许退出的Looper对象
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) { //线程只能执行一次,第二次执行就会抛出异常。
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            //取出刚才生成的Looper对象,赋值给sMainLooper
            //getMainLooper()可以获取这个成员变量
            sMainLooper = myLooper();
        }
    }


getMainLooper()

    public static Looper getMainLooper() {
        synchronized (Looper.class) {
            return sMainLooper;
        }
    }

prepare()

new一个Looper对象,保存在ThreadLocal中。这个方法只能执行一次。

    public static void prepare() {
    	//true表示允许退出,一般子线程的looper都是允许退出的。
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
    	//每个线程只允许执行一次该方法,第二次执行,线程的ThreadLocal已有数据,则会抛出异常。
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
         //创建Looper对象,并且保存到当前线程的ThreadLocal中
        sThreadLocal.set(new Looper(quitAllowed));
    }
    
    private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }

Looper对象不能直接创建,必须通过Looper来的两个public static方法prepare()或者prepareMainLooper()来间接创建。因为:Looper的构造方法是私有的。

myLooper()

从ThreadLocal里面取出Looper对象。

	// sThreadLocal.get() will return null unless you've called prepare().
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    
    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }

你可能感兴趣的:(Handler,java,开发语言)