handler全家桶

handler是android中实现线程之间通信的方式之一,他的原理值得我们了解。

handler的通信实现原理离不开MessageQueue,Message和Looper

当handler被创建的时候,会检查其内部引用的mLooper对象是否已经存在。

mLooper= Looper.myLooper();

if(mLooper==null) {

throw newRuntimeException(

"Can't create handler inside thread that has not called Looper.prepare()");

}

ThreadLocal是一种以当前thread为key的HashMap,能够将线程间的对象分离开来

public T get() {

Thread t = Thread.currentThread();

ThreadLocalMap map = getMap(t);

if(map !=null) {

ThreadLocalMap.Entry e = map.getEntry(this);

if(e !=null)

return(T)e.value;

}

return setInitialValue();

}

public void set(T value) {

Thread t = Thread.currentThread();

ThreadLocalMap map = getMap(t);

if(map !=null)

map.set(this,value);

else

createMap(t,value);

}

looper以threadlocal的形式存在于thread当中

调用looper.prepare的时候:

private static void prepare(boolean quitAllowed) {

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

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

}

sThreadLocal.set(newLooper(quitAllowed));

}

创建looper的时候会一同创建messageQueue:

private Looper(boolean quitAllowed) {

mQueue=new MessageQueue(quitAllowed);

mThread= Thread.currentThread();

}

在looper的loop方法中不断读取messageQueue的msg

代码:

public static void loop() {

finalLooper me =myLooper();

if(me ==null) {

throw newRuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");

}

finalMessageQueue queue = me.mQueue;

// Make sure the identity of this thread is that of the local process,

// and keep track of what that identity token actually is.

Binder.clearCallingIdentity();

final longident = Binder.clearCallingIdentity();

for(;;) {

Message msg = queue.next();// might block

if(msg ==null) {

// No message indicates that the message queue is quitting.

return;

}

// This must be in a local variable, in case a UI event sets the logger

finalPrinter logging = me.mLogging;

if(logging !=null) {

logging.println(">>>>> Dispatching to "+ msg.target +" "+

msg.callback +": "+ msg.what);

}

final longtraceTag = me.mTraceTag;

if(traceTag !=0&& Trace.isTagEnabled(traceTag)) {

Trace.traceBegin(traceTag,msg.target.getTraceName(msg));

}

try{

msg.target.dispatchMessage(msg);

}finally{

if(traceTag !=0) {

Trace.traceEnd(traceTag);

}

}

if(logging !=null) {

logging.println("<<<<< Finished to "+ msg.target +" "+ msg.callback);

}

// Make sure that during the course of dispatching the

// identity of the thread wasn't corrupted.

final longnewIdent = Binder.clearCallingIdentity();

if(ident != newIdent) {

Log.wtf(TAG,"Thread identity changed from 0x"

+ Long.toHexString(ident) +" to 0x"

+ Long.toHexString(newIdent) +" while dispatching to "

+ msg.target.getClass().getName() +" "

+ msg.callback +" what="+ msg.what);

}

msg.recycleUnchecked();

}

}

你可能感兴趣的:(handler全家桶)