Android Thread,Handler,Loop,Message,HandlerThread总结

问题:
1:Handle Thread Loop,MessageQueue的关系,他们是如何绑定的?

2:怎么指定线程处理Handle 发送的消息?

3:HandlerThread 与Thread 的区别,如何使用?

==================================================
解析:
Thread 是普通线程类,可以独立使用,跟java一样;

Loop:循环器,持有一个线程,跟一个MessageQueue, loop作用使Thread变成HandleThread,HandleThread就是循环工作的线程。在程序开发中(尤其是GUI开发中),我们经常会需要一个线程不断循环,一旦有新任务则执行,执行完继续等待下一个任务;

Handle: 消息发送,处理器,绑定一个Loop,发送消息由Loop执行放到MessageQueue,特定时候由Loop取出 交给对应的handle处理;

绑定关系:
1:handler初始化会绑定一个Loop,默认是获得当前线程的Loop;

public Handler(Looper looper, Callback callback, boolean async) {
    mLooper = looper;
    mQueue = looper.mQueue;
    mCallback = callback;
    mAsynchronous = 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) {
        }
    }
    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;
}

所以初始化Handler时可以传入指定Loop,之后handler发送的消息都将交由该Loop处理!不传入将获取绑定当前线程的Loop!

2:Loop
Loop.prepare() 会绑定当前线程,并且创建一个新的MessageQueue

//Loop 静态成员属性
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
//loop.prepare()
private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}

//构造函数
private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}

总结关系:
1:handler 持有一个Loop(有且只有一个,默认为绑定当前线程的Loop);
2:Loop 持有 Thread(有且只有一个),跟MessageQueue;(有且只有一个)
3:Loop.prepare() 会绑定当前线程,并且创建一个新的MessageQueue
4:一个Loop可以被多个handler 持有!!
5:handler发送的message 消息体会绑定自己标记,下次Loop取出Message时会跟进绑定的tag交回给对应handler

关系 :多个handler对应一个Loop对应一条线程对应一个MessageQueue!

HandlerThread :循环处理消息线程,内部与Loop绑定,对外提供本线程的loop,
与Handle 配合使用,在Handle初始化时可获得该线程对应Loop进行初始化;

//HandlerThread  run方法:
@Override
public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
}
//获取Loop
public Looper getLooper() {
    if (!isAlive()) {
        return null;
    }

    // If the thread has been started, wait until the looper has been created.
    synchronized (this) {
        while (isAlive() && mLooper == null) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
    }
    return mLooper;
}

使用:

//创建循环线程
HandlerThread handlerThread= new HandlerThread("tag");
handlerThread.start();

//初始化Handler 传入 HandlerThsread 的loop
Handler handler=new Handler(handlerThread.getLooper()){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//TODO 这里的代码都会在handlerThread 子线程执行!!!

}
};

这样使用handle 发送的消息都会被HandlerThread处理,且 handlerThread将一直阻塞轮询,直到调用 quit()方法!

猜你喜欢

转载自blog.csdn.net/lqb3732842/article/details/54947159