Handler(Looper.getMainLooper()).post () program principle
Distribute the queue message of the main thread in the loop method in the source code of ActivityThread in Android. The source code is as follows
for(;;){
Message msg = queue.next();// might blockif(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 loggerfinal Printer logging = me.mLogging;if(logging != null){
logging.println(">>>>> Dispatching to "+ msg.target +" "+
msg.callback +": "+ msg.what);}// Make sure the observer won't change while processing a transaction.final Observer observer = sObserver;finallong traceTag = me.mTraceTag;long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;long slowDeliveryThresholdMs = me.mSlowDeliveryThresholdMs;if(thresholdOverride >0){
slowDispatchThresholdMs = thresholdOverride;
slowDeliveryThresholdMs = thresholdOverride;}finalboolean logSlowDelivery =(slowDeliveryThresholdMs >0)&&(msg.when >0);finalboolean logSlowDispatch =(slowDispatchThresholdMs >0);finalboolean needStartTime = logSlowDelivery || logSlowDispatch;finalboolean needEndTime = logSlowDispatch;if(traceTag !=0&& Trace.isTagEnabled(traceTag)){
Trace.traceBegin(traceTag, msg.target.getTraceName(msg));}finallong dispatchStart = needStartTime ? SystemClock.uptimeMillis():0;finallong dispatchEnd;
Object token = null;if(observer != null){
token = observer.messageDispatchStarting();}long origWorkSource = ThreadLocalWorkSource.setUid(msg.workSourceUid);try{
msg.target.dispatchMessage(msg);if(observer != null){
observer.messageDispatched(token, msg);}
dispatchEnd = needEndTime ? SystemClock.uptimeMillis():0;}catch(Exception exception){
if(observer != null){
observer.dispatchingThrewException(token, msg, exception);}throw exception;}finally{
ThreadLocalWorkSource.restore(origWorkSource);if(traceTag !=0){
Trace.traceEnd(traceTag);}}if(logSlowDelivery){
if(slowDeliveryDetected){
if((dispatchStart - msg.when)<=10){
Slog.w(TAG,"Drained");
slowDeliveryDetected =false;}}else{
if(showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart,"delivery",
msg)){
// Once we write a slow delivery log, suppress until the queue drains.
slowDeliveryDetected =true;}}}if(logSlowDispatch){
showSlowLog(slowDispatchThresholdMs, dispatchStart, dispatchEnd,"dispatch", msg);}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.finallong newIdent = 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();}
Our current approach is equivalent to replacing the code below the code dividing line with the code in the post() function closure, namely:
for(;;){
Message msg = queue.next();// might blockif(msg == null){
// No message indicates that the message queue is quitting.return;}while(true){
try{
Looper.loop()}catch(Exception e ){
Log.d("xxx","${e.message}")
e.printStackTrace()errorHandler()}}}