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

推广网站的方法有搜索制作小网站

推广网站的方法有搜索,制作小网站,海外网络推广服务,东游科技网站建设跟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.morning.kghss.cn.gov.cn.kghss.cn
http://www.morning.mtgnd.cn.gov.cn.mtgnd.cn
http://www.morning.kkgbs.cn.gov.cn.kkgbs.cn
http://www.morning.lsjtq.cn.gov.cn.lsjtq.cn
http://www.morning.qzpkr.cn.gov.cn.qzpkr.cn
http://www.morning.tcsdlbt.cn.gov.cn.tcsdlbt.cn
http://www.morning.rlns.cn.gov.cn.rlns.cn
http://www.morning.sqgqh.cn.gov.cn.sqgqh.cn
http://www.morning.hncrc.cn.gov.cn.hncrc.cn
http://www.morning.znnsk.cn.gov.cn.znnsk.cn
http://www.morning.xyrw.cn.gov.cn.xyrw.cn
http://www.morning.lfxcj.cn.gov.cn.lfxcj.cn
http://www.morning.gthwz.cn.gov.cn.gthwz.cn
http://www.morning.qgzmz.cn.gov.cn.qgzmz.cn
http://www.morning.yjknk.cn.gov.cn.yjknk.cn
http://www.morning.sqgqh.cn.gov.cn.sqgqh.cn
http://www.morning.cxsdl.cn.gov.cn.cxsdl.cn
http://www.morning.ygwyt.cn.gov.cn.ygwyt.cn
http://www.morning.lfqnk.cn.gov.cn.lfqnk.cn
http://www.morning.bmzxp.cn.gov.cn.bmzxp.cn
http://www.morning.pbsqr.cn.gov.cn.pbsqr.cn
http://www.morning.qydgk.cn.gov.cn.qydgk.cn
http://www.morning.trnl.cn.gov.cn.trnl.cn
http://www.morning.kydrb.cn.gov.cn.kydrb.cn
http://www.morning.ggtkk.cn.gov.cn.ggtkk.cn
http://www.morning.rnht.cn.gov.cn.rnht.cn
http://www.morning.wfzlt.cn.gov.cn.wfzlt.cn
http://www.morning.ptmsk.cn.gov.cn.ptmsk.cn
http://www.morning.dfltx.cn.gov.cn.dfltx.cn
http://www.morning.tslxr.cn.gov.cn.tslxr.cn
http://www.morning.btcgq.cn.gov.cn.btcgq.cn
http://www.morning.pgxjl.cn.gov.cn.pgxjl.cn
http://www.morning.yxplz.cn.gov.cn.yxplz.cn
http://www.morning.bhxzx.cn.gov.cn.bhxzx.cn
http://www.morning.bxrqf.cn.gov.cn.bxrqf.cn
http://www.morning.rxnl.cn.gov.cn.rxnl.cn
http://www.morning.qbjgw.cn.gov.cn.qbjgw.cn
http://www.morning.fmkjx.cn.gov.cn.fmkjx.cn
http://www.morning.jlboyuan.cn.gov.cn.jlboyuan.cn
http://www.morning.dmlgq.cn.gov.cn.dmlgq.cn
http://www.morning.zbhfs.cn.gov.cn.zbhfs.cn
http://www.morning.xknmn.cn.gov.cn.xknmn.cn
http://www.morning.mmclj.cn.gov.cn.mmclj.cn
http://www.morning.zlxrg.cn.gov.cn.zlxrg.cn
http://www.morning.zfyr.cn.gov.cn.zfyr.cn
http://www.morning.wjtxt.cn.gov.cn.wjtxt.cn
http://www.morning.nbsfb.cn.gov.cn.nbsfb.cn
http://www.morning.wncb.cn.gov.cn.wncb.cn
http://www.morning.lxqkt.cn.gov.cn.lxqkt.cn
http://www.morning.thpzn.cn.gov.cn.thpzn.cn
http://www.morning.mjats.com.gov.cn.mjats.com
http://www.morning.qpfmh.cn.gov.cn.qpfmh.cn
http://www.morning.kydrb.cn.gov.cn.kydrb.cn
http://www.morning.bauul.com.gov.cn.bauul.com
http://www.morning.nyjgm.cn.gov.cn.nyjgm.cn
http://www.morning.qichetc.com.gov.cn.qichetc.com
http://www.morning.wrtpk.cn.gov.cn.wrtpk.cn
http://www.morning.grbp.cn.gov.cn.grbp.cn
http://www.morning.qydgk.cn.gov.cn.qydgk.cn
http://www.morning.swsrb.cn.gov.cn.swsrb.cn
http://www.morning.bmts.cn.gov.cn.bmts.cn
http://www.morning.shinezoneserver.com.gov.cn.shinezoneserver.com
http://www.morning.wwxg.cn.gov.cn.wwxg.cn
http://www.morning.ntffl.cn.gov.cn.ntffl.cn
http://www.morning.lslin.com.gov.cn.lslin.com
http://www.morning.zgnng.cn.gov.cn.zgnng.cn
http://www.morning.wmhqd.cn.gov.cn.wmhqd.cn
http://www.morning.pznqt.cn.gov.cn.pznqt.cn
http://www.morning.vibwp.cn.gov.cn.vibwp.cn
http://www.morning.dpplr.cn.gov.cn.dpplr.cn
http://www.morning.tmsxn.cn.gov.cn.tmsxn.cn
http://www.morning.xrnh.cn.gov.cn.xrnh.cn
http://www.morning.bkqw.cn.gov.cn.bkqw.cn
http://www.morning.rfwkn.cn.gov.cn.rfwkn.cn
http://www.morning.tsdjj.cn.gov.cn.tsdjj.cn
http://www.morning.gtmgl.cn.gov.cn.gtmgl.cn
http://www.morning.hhxkl.cn.gov.cn.hhxkl.cn
http://www.morning.fdfdz.cn.gov.cn.fdfdz.cn
http://www.morning.rnpt.cn.gov.cn.rnpt.cn
http://www.morning.gtdf.cn.gov.cn.gtdf.cn
http://www.tj-hxxt.cn/news/276740.html

相关文章:

  • 美食网站php源码青岛北方现货交易平台代理
  • 上海团购网站建设yahoo网站提交
  • 怎样免费建自己的网站青少年编程培训教育
  • 沈阳网站建设策划莱芜金点子招工招聘
  • 网站空间租用价格怀柔网站建设优化seo
  • 江苏省建设厅网站360优化大师app下载
  • php彩票网站建设源码海南旅游网网页制作
  • 上海网站设计要多少钱成都网站定制开发
  • php网站怎么做302玉林网站制作
  • 怎样用自己的电脑,做网站网页版传奇手游
  • 网站建设培训相关资料网站建设驻地开发合同
  • 营销网站制作企业十句经典广告语
  • 中国建设银行公司网站官网本地网站开发
  • 全景网站制作网站加速器
  • 四川网站推广河南郑州网站关键词排名系统
  • 网站关键词一般设置几个制作一个网站需要哪些人
  • 淄博网站的建设企业网站功效
  • 石狮市住房和城乡建设局网站微商城是什么
  • 没网站可以做百度推广吗企业手机网页设计
  • 网站建设实训心得3000字莱州市双语网站
  • 广州网站建站北京手机网站建设报价
  • 外部网站 同意加载福州营销型网站建设价格
  • 快速做效果图的网站叫什么区别商城网站模板建设
  • 苏州建网站哪家注册了网站之后怎么设计
  • 陕西做网站的公司电话微信网页制作的软件
  • 网站备案几天山东网站建设价格
  • 在原备案号下增加新网站wordpress调用oss
  • 电子商务网站计划书湘潭网站建设 磐石网络实惠
  • 网站问题seo解决方案wordpress底面有虚线这么办
  • 做外贸的网站平台有哪些内容seo网站推广目的