Android Handler机制的工作原理详析

2019-07-31 09:57| 发布者: |






looper.prepare;
looper.loop;

public static void prepare {
 prepare;
private static void prepare {
 if  != null) {
 throw new runtimeexception;
 sthreadlocal.set);
private looper {
 mqueue = new 九卅娱乐官方网站网址messagequeue;
 mthread = thread.currentthread;
}

public static void loop {
 // 判断当前线程有没有初始化looper
 final looper me = mylooper;
 if  {
 throw new runtimeexception wasn't called on this thread.");
 final messagequeue queue = me.mqueue;
 for  {
 message msg = queue.next; // might block
 if  {
 // no message indicates that the message queue is quitting.
 return;
 final long tracetag = me.mtracetag;
 if ) {
 trace.tracebegin);
 try {
 // target指的是handler
 msg.target.dispatchmessage;
 } finally {
 if  {
 trace.traceend;
 msg.recycleunchecked;
}





message next {
 int pendingidlehandlercount = -1; // -1 only during first iteration
 int nextpolltimeoutmillis = 0;
 for  {
 if  {
 binder.flushpendingcommands;
 nativepollonce;
 synchronized  {
 // try to retrieve the next message. return if found.
 final long now = systemclock.uptimemillis;
 message prevmsg = null;
 message msg = mmessages;
 if  {
 // stalled by a barrier. find the next asynchronous message in the queue.
 do {
 prevmsg = msg;
 msg = msg.next;
 } while );
 if  {
 if  {
 // next message is not ready. set a timeout to wake up when it is ready.
 nextpolltimeoutmillis =  math.min;
 } else {
 // got a message.
 mblocked = false;
 if  {
 prevmsg.next = msg.next;
 } else {
 mmessages = msg.next;
 msg.next = null;
 if  log.v;
 msg.markinuse;
 return msg;
 } else {
 // no more messages.
 nextpolltimeoutmillis = -1;
 // process the quit message now that all pending messages have been handled.
 if  {
 dispose;
 return null;
 // if first time idle, then get the number of idlers to run.
 // idle handles only run if the queue is empty or if the first message
 // in the queue  is due to be handled in the future.
 if ) {
 pendingidlehandlercount = midlehandlers.size;
 if  {
 // no idle handlers to run. loop and wait some more.
 mblocked = true;
 continue;
 if  {
 mpendingidlehandlers = new idlehandler[math.max];
 mpendingidlehandlers = midlehandlers.toarray;
 // run the idle handlers.
 // we only ever reach this code block during the first iteration.
 for  {
 final idlehandler idler = mpendingidlehandlers[i];
 mpendingidlehandlers[i] = null; // release the reference to the handler
 boolean keep = false;
 try {
 keep = idler.queueidle;
 } catch  {
 log.wtf;
 if  {
 synchronized  {
 midlehandlers.remove;
 // reset the idle handler count to 0 so we do not run them again.
 pendingidlehandlercount = 0;
 // while calling an idle handler, a new message could have been delivered
 // so go back and look again for a pending message without waiting.
 nextpolltimeoutmillis = 0;
}


nativepollonce;






handler.send___;
handler.post___;

boolean enqueuemessage {
 synchronized  {
 msg.markinuse;
 msg.when = when;
 message p = mmessages;
 boolean needwake;
 if  {
 // new head, wake up the event queue if blocked.
 msg.next = p;
 mmessages = msg;
 needwake = mblocked;
 } else {
 // inserted within the middle of the queue. usually we don't have to wake
 // up the event queue unless there is a barrier at the head of the queue
 // and the message is the earliest asynchronous message in the queue.
 needwake = mblocked && p.target == null && msg.isasynchronous;
 message prev;
 for  {
 prev = p;
 p = p.next;
 if  {
 break;
 if ) {
 needwake = false;
 msg.next = p; // invariant: p == prev.next
 prev.next = msg;
 // we can assume mptr != 0 because mquitting is false.
 if  {
 nativewake;
 return true;
}


public void dispatchmessage {
 if  {
 handlecallback;
 } else {
 if  {
 if ) {
 return;
 handlemessage;
}


还记得looper中有一个threadlocal吧,把它放到最后来讲是因为它可以单独拿出来讲,不想在上面干扰到整个流程。




public void set {
 thread t = thread.currentthread;
 threadlocalmap map = getmap;
 if 
 map.set;
 else
 createmap;
}

threadlocalmap getmap {
 return t.threadlocals;
}

看到这里,大概也能明白了。每个线程thread中有一个threadlocalmap对象。通过threadlocal.set方法,实际上是去获取当前线程中的threadlocalmap,线程不同,获取到的threadlocalmap自然也不同。
再来看看这个threadlocalmap是什么来头。看类的注释中有这么一句话:


threadlocalmap is a customized hash map suitable only for maintaining thread local values.



public t get {
 thread t = thread.currentthread;
 threadlocalmap map = getmap;
 if  {
 threadlocalmap.entry e = map.getentry;
 if  {
 @suppresswarnings
 t result = e.value;
 return result;
 return setinitialvalue;
}

虽然在开始写之前,觉得handler机制比较简单,好像没啥必要写,但真正要写起来的时候还是得去深入了解代码的细节,然后才发现有些地方以前理解得也不够好。能理解和能写出来让别人理解,其实是不同的层次了。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对萬仟网的支持。

<
>
关于我们
AB模版网成立于2014年,我们是一家专注用户体验设计开发与互联网品牌建设的设计公司,创立至今为2000多位客户提供了创新与专业的设计方案。设计服务范围包括:交互原型设计、产品视觉设计、网站设计与开发建设、移动及软件产品界面设计、图标设计、品牌及平面设计等。

联系我们

13588889999服务时间:9:00-18:00)

admin@adminbuy.cn

官方微信官方微信

部门热线

前   台:13588889999
业务部:13588889999
客服部:13588889999
技术部:13566667777
人事部:13566667777

咨询电话13588889999 返回顶部
返回顶部