当前位置: 首页 > news >正文

佛山高端网站设计dw主页制作

佛山高端网站设计,dw主页制作,炒股配资网站开发,html5做网站链接跟Handler有关系的#xff0c;包括Thread#xff0c;Looper#xff0c;Handler#xff0c;MessageQueue Looper: 由于Looper是android包加入的类#xff0c;而Thread是java包的类#xff0c;所以#xff0c;想要为Thread创建一个Looper#xff0c;需要在线程内部调用…跟Handler有关系的包括ThreadLooperHandlerMessageQueue Looper: 由于Looper是android包加入的类而Thread是java包的类所以想要为Thread创建一个Looper需要在线程内部调用Looper.prepare Looper内部会存储一个ThreadLocal因此每个线程都会有自己的一个Looper。 Looper内部有自己存储了一个MessageQueue以及主线程的MainLooper。 调用Looper一般会有两个方法Looper.prepare以及Looper.loop方法 Looper.prepare prepare会新创建一个Looper塞进ThreadLocal因此prepare必须在线程内部调用才能将线程本身作为key。 同时会创建MessageQueue以及存储当前线程。 顺便看下两个比较常用的方法 myLooper是从ThreadLocal中获取的当前线程所属的Looper。 myQueue对应的是当前线程的Looper中存储的MessageQueue。 Looper.loop 从Looper.loop方法可以看出几个细节 通过调用MessageQueue.next获取下一个要处理的Message通过Message.target.dispatchMessage将Message提交给Message中存储的Handler去处理Handler调用dispatchMessage可以创建一个进程唯一的Observer去监听Message的分配以及处理结束的进度。 public static void loop() {final Looper me myLooper();if (me null) {throw new RuntimeException(No Looper; Looper.prepare() wasnt called on this thread.);}if (me.mInLoop) {Slog.w(TAG, Loop again would have the queued messages be executed before this one completed.);}me.mInLoop true;final MessageQueue queue me.mQueue;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 wont change while processing a transaction.final Observer observer sObserver;final long traceTag me.mTraceTag;long slowDispatchThresholdMs me.mSlowDispatchThresholdMs;long slowDeliveryThresholdMs me.mSlowDeliveryThresholdMs;if (thresholdOverride 0) {slowDispatchThresholdMs thresholdOverride;slowDeliveryThresholdMs thresholdOverride;}final boolean logSlowDelivery (slowDeliveryThresholdMs 0) (msg.when 0);final boolean logSlowDispatch (slowDispatchThresholdMs 0);final boolean needStartTime logSlowDelivery || logSlowDispatch;final boolean needEndTime logSlowDispatch;if (traceTag ! 0 Trace.isTagEnabled(traceTag)) {Trace.traceBegin(traceTag, msg.target.getTraceName(msg));}final long dispatchStart needStartTime ? SystemClock.uptimeMillis() : 0;final long 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 wasnt corrupted.final long 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();} } Message 从Looper.loop方法可以看出会对Looper的MessageQueue遍历不断取出Message然后调用Message.target.dispatchMessage方法。 从Message的变量可以看出target实际是Message所属的Handler。 同时Message存储了一个next说明MessageQueue是一个链式结构。 MessageQueue https://www.cnblogs.com/jiy-for-you/p/11707356.html 从MessageQueue.next可以获取几个有效信息 nativePollOnceMessageQueue中没有Message的时候会卡在这个方法类似于object.wait当有人调用MessageQueue.enqueueMessage方法的时候会将线程唤醒。msg.target null代表该msg是一个同步屏障即阻拦同步消息的执行。遇到同步屏障时会往后遍历优先执行异步消息触发view的绘制的那个消息就是异步消息。如果获取到一个msgmsg.when代表的执行时间还没到会先去执行IdleHandler里面的消息或MessageQueue队列为空。 // MessageQueue.next Message next() {// Return here if the message loop has already quit and been disposed.// This can happen if the application tries to restart a looper after quit// which is not supported.final long ptr mPtr;if (ptr 0) {return null;}int pendingIdleHandlerCount -1; // -1 only during first iterationint nextPollTimeoutMillis 0;for (;;) {if (nextPollTimeoutMillis ! 0) {Binder.flushPendingCommands();}// 如果没有消息会卡在这个方法nativePollOnce(ptr, nextPollTimeoutMillis);synchronized (this) {// Try to retrieve the next message. Return if found.final long now SystemClock.uptimeMillis();Message prevMsg null;Message msg mMessages;if (msg ! null msg.target null) {// 同步屏障当遇到同步屏障,会往后寻找异步消息isAsynchronous执行// Stalled by a barrier. Find the next asynchronous message in the queue.do {// 遍历直到找到一个异步的msgprevMsg msg;// 这一步prevMsg!null这会导致msg msg.next;} while (msg ! null !msg.isAsynchronous());}if (msg ! null) {if (now msg.when) {// msg.when是这个message的执行时间如果message的执行时间在now之后// Next message is not ready. Set a timeout to wake up when it is ready.nextPollTimeoutMillis (int) Math.min(msg.when - now, Integer.MAX_VALUE);} else {// Got a message.mBlocked false;if (prevMsg ! null) {prevMsg.next msg.next;} else {mMessages msg.next;}msg.next null;if (DEBUG) Log.v(TAG, Returning message: msg);msg.markInUse();return msg;}} else {// No more messages.nextPollTimeoutMillis -1;}// Process the quit message now that all pending messages have been handled.if (mQuitting) {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 (possibly a barrier) is due to be handled in the future.// 走到这说明消息队列是空的或队首是一个延迟执行的Messageif (pendingIdleHandlerCount 0 (mMessages null || now mMessages.when)) {pendingIdleHandlerCount mIdleHandlers.size();}if (pendingIdleHandlerCount 0) {// No idle handlers to run. Loop and wait some more.mBlocked true;continue;}if (mPendingIdleHandlers null) {mPendingIdleHandlers new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];}mPendingIdleHandlers mIdleHandlers.toArray(mPendingIdleHandlers);}// Run the idle handlers.// We only ever reach this code block during the first iteration.for (int i 0; i pendingIdleHandlerCount; i) {final IdleHandler idler mPendingIdleHandlers[i];mPendingIdleHandlers[i] null; // release the reference to the handlerboolean keep false;try {keep idler.queueIdle();} catch (Throwable t) {Log.wtf(TAG, IdleHandler threw exception, t);}if (!keep) {synchronized (this) {mIdleHandlers.remove(idler);}}}// 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;} }Handler的总结 Handler内部一定会有一个Looper。Looper跟线程一一绑定。绑定的关系存在Looper的sThreadLocal中。所以如果Handler想要监听哪个线程上的消息可以直接给Handler传那个线程的Looper即可。Looper实际上是一个轮询消息的机制所以内部一定会存在一个MessageQueue。当Looper开始轮询的时候调用Looper.loop会每次调用MessageQueue.next取一个Message出来执行。Looper获取到Message之后会调用Message.target.dispatchMessage方法。即实际调用的是Handler.dispatchMessage的方法。Message中有几个比较重要的参数 target这个Message从属于哪个handler从哪个handler post过去的。callback当调用handler.postRunnable即创建了一个Messagemsg.callBack runnable。what这个Message的唯一标识id。当Handler.handleMessage方法中会接收多个message通过what区分这个Message的类别。when通过handler.postDelayed设置这个Message实际应该执行的时间curTimedelay。MessageQueue的入队实际是通过when去进行Message的排序的。handler.dispatchMessage方法 如果Message.callback ! null直接执行Message.callback.run即post(Runnable)中Runnable的执行。否则如果给handler设置了Callback就调用Callback.handleMessage否则调用Handler本身的handleMessage方法空实现需要重写。 关于barrier // MessageQueue private int postSyncBarrier(long when) {// Enqueue a new sync barrier token.// We dont need to wake the queue because the purpose of a barrier is to stall it.synchronized (this) {final int token mNextBarrierToken;final Message msg Message.obtain();msg.markInUse();msg.when when;msg.arg1 token;// 代表Message的barrier特征是target nullMessage prev null;Message p mMessages;if (when ! 0) {// 根据when将代表barrier的msg插入MessageQueuewhile (p ! null p.when when) {prev p;p p.next;}}if (prev ! null) { // invariant: p prev.nextmsg.next p;prev.next msg;} else {msg.next p;mMessages msg;}return token;} } postSyncBarrier生成一个target null的Message根据when插入MessageQueue中。返回的token是barrier的唯一标识。只要postSyncBarrier就要根据这个token后面移除barrier。否则会导致同步消息一直无法执行。 看下有了barrier的MessageQueue取Message的时候是怎么表现的。 Message next() {// Return here if the message loop has already quit and been disposed.// This can happen if the application tries to restart a looper after quit// which is not supported.final long ptr mPtr;if (ptr 0) {return null;}int pendingIdleHandlerCount -1; // -1 only during first iterationint nextPollTimeoutMillis 0;for (;;) {if (nextPollTimeoutMillis ! 0) {Binder.flushPendingCommands();}nativePollOnce(ptr, nextPollTimeoutMillis);// nextPollTimeoutMillis:等待的时间synchronized (this) {// Try to retrieve the next message. Return if found.final long now SystemClock.uptimeMillis();Message prevMsg null;Message msg mMessages;if (msg ! null msg.target null) {// 如果取msg的时候队首的Msg是Barrier// Stalled by a barrier. Find the next asynchronous message in the queue.do {prevMsg msg;msg msg.next;// 就一直往后遍历寻找一个异步的msg} while (msg ! null !msg.isAsynchronous());}if (msg ! null) {if (now msg.when) {// 如果还没到msg的执行时间就设置nextPollTimeoutMillis// Next message is not ready. Set a timeout to wake up when it is ready.nextPollTimeoutMillis (int) Math.min(msg.when - now, Integer.MAX_VALUE);} else {// Got a message.mBlocked false;if (prevMsg ! null) {prevMsg.next msg.next;} else {mMessages msg.next;}msg.next null;if (DEBUG) Log.v(TAG, Returning message: msg);msg.markInUse();return msg;}} else {// 如果mMessages队列为空或有Barrier的时候异步msg为空就设置等待时间为-1// 为-1代表等待被唤醒// No more messages.nextPollTimeoutMillis -1;}// Process the quit message now that all pending messages have been handled.if (mQuitting) {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 (possibly a barrier) is due to be handled in the future.if (pendingIdleHandlerCount 0 (mMessages null || now mMessages.when)) {pendingIdleHandlerCount mIdleHandlers.size();}// 如果队列为空或者还没到message的执行时间开始执行IdleHandlerif (pendingIdleHandlerCount 0) {// No idle handlers to run. Loop and wait some more.mBlocked true;continue;}if (mPendingIdleHandlers null) {mPendingIdleHandlers new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];}mPendingIdleHandlers mIdleHandlers.toArray(mPendingIdleHandlers);}// Run the idle handlers.// We only ever reach this code block during the first iteration.for (int i 0; i pendingIdleHandlerCount; i) {final IdleHandler idler mPendingIdleHandlers[i];mPendingIdleHandlers[i] null; // release the reference to the handlerboolean keep false;try {keep idler.queueIdle();} catch (Throwable t) {Log.wtf(TAG, IdleHandler threw exception, t);}if (!keep) {synchronized (this) {mIdleHandlers.remove(idler);}}}// Reset the idle handler count to 0 so we do not run them again.// 防止下次再走一遍IdleHandlerpendingIdleHandlerCount 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.// 经过IdleHandler之后可能已经有Message入队了再遍历一遍第二次就直接等待了。nextPollTimeoutMillis 0;} } 总结下next的逻辑 如果mMessages的队首是barrier(msg.target null)就遍历messages优先执行异步消息异步消息一般是优先级最高的信息比如响应input事件或是view刷新。。如果不是barrier就直接取队首的message执行。如果12步骤取到的message ! null先看message的when now大于则直接返回message给Looper.loop方法。小于则设置nextPollTimeoutMillis用来设置线程的等待时间nativePollOnce。如果messageQueue为空或message.when now(即要等待)那么这个时候就去执行IdleHandler。 总结下上面nativePollOnce其实代表线程在等待下一个消息的执行或者messages队列为空。或者是设置了barrier情况下没有异步消息的时候。 下一步看下MessageQueue的具体打出日志代表什么。
http://www.w-s-a.com/news/498241/

相关文章:

  • 如何建设网站论坛凡科建站手机版登录
  • 建设银行门户网站惠州公司网站建设价格
  • 用python开发网站网站如何取消验证码
  • 公司做企业网站互联网建网站
  • 建网站需要的费用公司注册后怎么做网站
  • 宣传电脑的网站开发运动网站建设教程
  • 网站建设公司都会有哪些花销做网站公司商丘
  • 网站风格有哪些软件定制和开发
  • 公司网络维护具体做什么河南网站推广优化公司哪家好
  • 中学生制作的网站常平哪里有招计算机网站开发的
  • 原创网站模版苏州响应式网站建设
  • 做海报在哪个网站可以找素材网址申请注册方法
  • 网站建设分哪些类别别人做的网站不能用
  • 做网站网站会怎么样全国高校校园网站联盟建设
  • 整站下载器 做网站地图地产项目网站设计
  • 创意设计网站公司手机wap网站建设多少钱
  • 甘肃省第八建设集团公司网站seo高级优化方法
  • 精美的商城网站介绍最多人用的wordpress子主题
  • 检察门户网站建设情况俄外长抵达北京
  • 老电脑做网站服务器网站在线留言如何做
  • 南宁广告公司网站建设小程序源码破解
  • 沛县做网站xlec网站建设开发方式包括哪些方面
  • 山西网站建设 哪家好四川城乡和建设厅网站
  • 有瀑布流的网站小型商城网站
  • 百石网怎么做网站二次开发软件
  • 网站域名是什么东西制作网页哪家好
  • 合肥网站建设团队简述网站内容管理流程
  • 网站广告是内容营销吗wordpress增加背景图片
  • 网站建设技术jsp课程设计响应式布局网站开发
  • 东莞网站排名优化seo套路网站怎么做的