Android之Looper

        Looper:循环器,是一个用于使线程运行一个消息(Message)循环的类。线程默认没有关联的消息循环,在建立它以前,在将要运行循环的线程中调用prepare方法,而后loop方法会处理消息直到循环结束。 java

        绝大多数消息循环是经过Handler类来Looper交互的。 ide

        下面是实现了Looper的线程的一个典型例子,使用分离的prepare方法和loop方法来建立一个用于跟Looper沟通的初始Handler。 oop

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

        先看准备工做的prepare方法: ui

public static final void prepare() {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper());
}

        每条线程只能绑定一个Looper,不然会抛出RuntimeException异常。若是不调用prepare方法,sThreadLocal.get()就会返回null。注意这是个静态方法,在最后一行中绑定了一个作为Looper的线程。怎么绑定的呢,看看Looper的一个私有无参构造方法: spa

private Looper() {
    mQueue = new MessageQueue();
    mRun = true;
    mThread = Thread.currentThread();
}

        构造方法里初始化了一个消息队列、一个运行状态的标志以及绑定一个线程(建立者所在的线程)。prepare方法给了一个在真正的循环开始以前,参照Looper建立一个Handler的机会。注意:在run方法中初始化Handler以前,必须调用Looper.prepare(),否则会抛出一个运行时异常,由于Handler须要一个从Looper获得的消息队列(即构造方法里面的mQueue)。调用prepare方法后必定要调用loop方法,而且调用quit方法退出循环。 线程

        接下来,看看在当前线程里运行一个消息队列的loop方法,用完后必定要调用quit方法结束循环: code

public static final void loop() {
    Looper me = myLooper();
    MessageQueue queue = me.mQueue;
    while (true) {
        Message msg = queue.next(); // might block
        if (msg != null) {
            if (msg.target == null) {
                // No target is a magic identifier for the quit message.
                return;
            }
            msg.target.dispatchMessage(msg);
            msg.recycle();
        }
    }
}

        高潮来了,上面说过,Looper的mQueue是Handler使用的消息队列,loop方法启动一个死循环从队列中获取数据,当队列中没有数据时,queue.next()会阻塞。当有数据时,msg.target(即Handler)就会调用dispatchMessage方法,进而调用Handler的handleCallback或者handlerMessage方法。从这些也能够知道,若是Handler是在子线程的run方法中建立(以前必须调用Looper.prepare())的,那么这个Handler的handleMessage或者handleCallback方法就是运行在子线程的。 队列

相关文章
相关标签/搜索