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

营销网站的建造步骤营销网站 需求说明

营销网站的建造步骤,营销网站 需求说明,璧山集团网站建设,企业网络服务目录 一、前言 二、Handler对象 在新启动的子线程发送消息#xff08;源码跟踪#xff09; 三、在主线程中#xff0c;回调 handleMessage 方法的流程是怎样的呢#xff1f; 四、总结说 1、主要由四个部分组成 ①. Message #xff08;主要用于携带消息#xff09;… 目录 一、前言 二、Handler对象 在新启动的子线程发送消息源码跟踪 三、在主线程中回调 handleMessage 方法的流程是怎样的呢 四、总结说 1、主要由四个部分组成 ①. Message 主要用于携带消息 ②. Handler 主要用于发送和处理消息 ​​​​​​​③. MessageQueue 它是一个消息队列 ​​​​​​​④. Looper 它是一个循环器 2、常见用法与源码解读 1、子线程 2、主线程 ​​​​​​​ 系列文章 Handler异步消息传递机制一Handler常用基本用法 Handler异步消息传递机制二在子线程中创建Handler Handler异步消息传递机制三在主线程、子线程中创建Handler源码Android 9.0解析 Handler异步消息传递机制四Handler发送消息流程源码Android 9.0解析 一、前言 上篇文章我们从源码角度分析了如何在主线程、子线程创建Handler对象。详细可参考Handler异步消息传递机制三在主线程、子线程中创建Handler源码Android 9.0彻底解析  那么创建Handler之后如何发送消息呢这个流程相信大家也已经非常熟悉了我们继续以文章 Handler异步消息传递机制一Handler常用实现方式 的demo为例然后进行源码跟踪解析 二、Handler对象 在新启动的子线程发送消息源码跟踪 下面是 Handler对象在新启动的子线程发送消息  的代码 public class DownLoadAppFile {public void download(String urlPath, Handler handler, ProgressBar pb) {try {//下载apk的代码这里用线程睡眠模拟Thread.currentThread().sleep(3*1000);} catch (InterruptedException e) {e.printStackTrace();}Message msg Message.obtain();msg.what 1;//成功//msg.what 2;//失败handler.sendMessage(msg);//发送消息} } Handler 到底是把 Message 发送到哪里去了呢 为什么之后又可以在 Handler 的 handleMessage 方法中重新得到这条Message呢 接下来我们来看一下发送消息的源码 public final boolean sendMessage(Message msg){return sendMessageDelayed(msg, 0);} 它里面调用了sendMessageDelayed方法 往下追踪 public final boolean sendMessageDelayed(Message msg, long delayMillis){if (delayMillis 0) {delayMillis 0;}return sendMessageAtTime(msg, SystemClock.uptimeMillis() delayMillis);} 我们可以看到 sendMessageDelayed 方法其中 msg 参数就是我们发送的 Message 对象 而 delayMillis 参数则表示延迟发送消息的时间毫秒这里默认传入的为0 往下追踪 public boolean sendMessageAtTime(Message msg, long uptimeMillis) {MessageQueue queue mQueue;if (queue null) {RuntimeException e new RuntimeException(this sendMessageAtTime() called with no mQueue);Log.w(Looper, e.getMessage(), e);return false;}return enqueueMessage(queue, msg, uptimeMillis);} 我们可以看到 sendMessageAtTime 方法同样接收两个参数其中msg参数就是我们发送的 Message 对象 而 uptimeMillis 参数则表示发送消息的时间SystemClock.uptimeMillis() delayMillis 即它的值等于自系统开机到当前时间的毫秒数再加上延迟时间。 然后对 MessageQueue 对象 queue 进行了赋值这个 MessageQueue 又是什么东西呢 学过java基础的可能会马上想到Queue基本上一个队列就是一个先入先出FIFO的数据结构。 同样在这里 MessageQueue  直译过来就是 消息队列 的意思用于将所有收到的消息以队列的形式进行排列并提供入队和出队的方法。 那么 enqueueMessage 方法就是入队的方法了我们来看下这个方法的源码 private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {msg.target this;if (mAsynchronous) {msg.setAsynchronous(true);}return queue.enqueueMessage(msg, uptimeMillis);} msg.target this;  即msg.target 赋值为 this也就是把当前所在类 Handler作为 msg 的 target 属性。 然后将这三个参数都传递到 MessageQueue 的 enqueueMessage 方法中 也就是说handler发出的消息最终会保存到消息队列中去。 调用 sendMessage 方法其实最后是调用了类 MessageQueueen 消息队列的 enqueueMessage 入队方法。 那么有了 MessageQueue 消息队列的 enqueueMessage 入队方法它必然有相对应的出队方法。 Handler 对象在新启动的子线程发送消息以后接下来在主线程中Handler类处理消息的方法 handleMessage 被自动回调。 三、在主线程中回调 handleMessage 方法的流程是怎样的呢 那么接下来在主线程中回调 handleMessage 方法的流程是怎样的呢 Android的主线程就是 ActivityThread主线程的入口方法为main我们继续来看一下 ActivityThread 类中main方法的源代码 public static void main(String[] args) {Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ActivityThreadMain);// CloseGuard defaults to true and can be quite spammy. We// disable it here, but selectively enable it later (via// StrictMode) on debug builds, but using DropBox, not logs.CloseGuard.setEnabled(false);Environment.initForCurrentUser();// Set the reporter for event logging in libcoreEventLogger.setReporter(new EventLoggingReporter());// Make sure TrustedCertificateStore looks in the right place for CA certificatesfinal File configDir Environment.getUserConfigDirectory(UserHandle.myUserId());TrustedCertificateStore.setDefaultUserDirectory(configDir);Process.setArgV0(pre-initialized);Looper.prepareMainLooper();// Find the value for {link #PROC_START_SEQ_IDENT} if provided on the command line.// It will be in the format seq114long startSeq 0;if (args ! null) {for (int i args.length - 1; i 0; --i) {if (args[i] ! null args[i].startsWith(PROC_START_SEQ_IDENT)) {startSeq Long.parseLong(args[i].substring(PROC_START_SEQ_IDENT.length()));}}}ActivityThread thread new ActivityThread();thread.attach(false, startSeq);if (sMainThreadHandler null) {sMainThreadHandler thread.getHandler();}if (false) {Looper.myLooper().setMessageLogging(newLogPrinter(Log.DEBUG, ActivityThread));}// End of event ActivityThreadMain.Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);Looper.loop();throw new RuntimeException(Main thread loop unexpectedly exited);}第47行调用了 Looper.loop() 方法这个方法内部执行了消息循环我们来看下它的源码 public static void loop() {final Looper me myLooper();if (me null) {throw new RuntimeException(No Looper; Looper.prepare() wasnt called on this thread.);}final MessageQueue 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 long ident Binder.clearCallingIdentity();// Allow overriding a threshold with a system prop. e.g.// adb shell setprop log.looper.1000.main.slow 1 stop startfinal int thresholdOverride SystemProperties.getInt(log.looper. Process.myUid() . Thread.currentThread().getName() .slow, 0);boolean slowDeliveryDetected false;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);}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;try {msg.target.dispatchMessage(msg);dispatchEnd needEndTime ? SystemClock.uptimeMillis() : 0;} finally {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();}} 我们可以看到前面几行代码首先对 Looper、MessageQueue 对象进行了赋值 然后第23行进入了一个死循环for( ; ; ){ }然后不断地调用的 MessageQueue 的 next 方法 Message msg queue.next() 很明显这个 next 方法就是消息队列的出队方法。 接下来你会发现第57行执行了 msg.target.dispatchMessage(msg); 其中 msg.targe t就是指的 Handler 对象你回看一下上面enqueueMessage()方法就可以看出来。 接下来当然就要看一看 Handler 中 dispatchMessage 方法的源码了如下 /*** Handle system messages here.*/public void dispatchMessage(Message msg) {if (msg.callback ! null) {handleCallback(msg);} else {if (mCallback ! null) {if (mCallback.handleMessage(msg)) {return;}}handleMessage(msg);}} 在第8行进行判断如果 mCallback 不为空则调用 mCallback 的 handleMessage 方法 否则直接调用Handler的handleMessage方法并将消息对象作为参数传递过去。 这样我相信大家就都明白了为什么 handleMessage 方法中可以获取到之前发送的消息了吧 四、总结说 1、主要由四个部分组成 ①. Message 主要用于携带消息 在线程之间传递可在内部携带少量信息用于不同线程之间交换数据 可以使用what、arg1、arg2字段携带整型数据 obj字段携带Object对象 ​​​​​​​②. Handler 主要用于发送和处理消息 1、如果看过Handler源码你会知道 Handler 构造器 做了 Looper 对象是否为空的判定 也就是创建Handler对象之前必须拥有不为null的Looper对象。 所以子线程创建Handler后会报错它需要调用 prepare()方法。 2、我们平时可以直接在主线程中使用Handler 那是因为在应用程序启动时在入口的main方法中已经默认为我们创建好了Looper。 主线程中内部调用了Looper的prepareMainLooper方法 而prepareMainLooper方法里面调用了Looper的prepare() 方法所以不会报错。 3、sendMessage方法用来发送消息最终会回到handleMessage方法进行处理。 ​​​​​​​③. MessageQueue 它是一个消息队列 1、先入先出FIFO的数据结构。 主要存放所有通过Handler发送的消息 它们会一直存在于队列中等待被处理 2、每个线程只有一个MessageQueue。 enqueueMessage 入队方法next 出队方法 ​​​​​​​④. Looper 它是一个循环器 调用loop方法后会不断从MessageQueue 取出待处理的消息 然后传递到handleMessage进行处理 2、常见用法与源码解读 1、子线程 Handler对象调用 sendMessage 等方法发送消息源码内部在调用过程中得到 MessageQueue 对象它是先入先出的队列 其实最后是调用MessageQueue 消息队列的 enqueueMessage 入队方法收到的消息以队列的形式进行排列 2、主线程 Android 的主线程就是 ActivityThread主线程的入口为main方法main方法内部 1Looper 调用 prepareMainLooper 静态方法内部会去调用 prepare 方法创建 一个Looper对象 方法内部具体 判读是否有Looper对象 有提示 “每个线程只能创建一个 Looper对象”没有创建一个新的Looper设置进去 2Looper调用 loop 方法loop方法内部 首先调用 myLooper 方法去取一个Looper对象 如果Looper对象为空会抛出一个异常提示没有Looper对象 如果Looper不为空继续执行得到 MessageQueueen 消息队列然后进行 for循环操作 for循环里面是 MessageQueueen 对象调用 next 出队方法得到一个个Message 消息调用dispatchMessage发送消息 最后通过回调 handleMessage 方法并把 Message 消息依次传递过去。 这里采用网上的一张图个人感觉图片概括得很好就没必要再去造同样的轮子了在新窗口打开可浏览大图 不错博文可参考 Android异步消息处理机制完全解析带你从源码的角度彻底理解_郭霖的专栏-CSDN博客_android 异步消息 Android进阶——Android消息机制之Looper、Handler、MessageQueen_点击置顶文章查看博客目录全站式导航-CSDN博客_handler looper
http://www.w-s-a.com/news/625189/

相关文章:

  • 大连网站优化技术长沙高端网站建设服务
  • 郎创网站建设做的网站 v2ex
  • 广东网站建设教程江西城乡住房建设网站
  • 做ppt卖给网站wordpress insert
  • 文化传媒公司网站模板wordpress转typecho
  • 网站建设设计视频郑州 服装网站建设
  • 网站建设什么公司好织梦cms默认密码
  • 大型网站 空间网上商城官网入口
  • 成都全美网站建设江苏专业网站建设
  • 足球网站模板有帮忙做阿里巴巴网站的吗
  • 建设厅报名网站京东网站的建设与发展前景
  • 金寨县住房和城乡建设部网站网页作业怎么做一个网站
  • 做ppt模板网站有哪些内容wap是什么意思卡老师
  • 网站建设一定要域名吗网站后台关键词设置
  • 标书制作公司网站坪山网站建设哪家便宜
  • 防止做网站的人修改数值门户网站架构
  • 电子项目外包网站考二建需要什么学历和专业
  • 做网站推广引流效果好吗电商推广技巧
  • 亦庄网站建设价格广州网站推广服务
  • 十大免费ppt网站下载重庆在线高校平台登录
  • 做环保网站案例百度seo教程
  • 体育用品网站模板网站建设话术
  • 潍坊网站建设服务商做网站多久能盈利
  • 嘉定区做网站房产信息查询官网
  • 网站直播间 是怎么做的唐山论坛建站模板
  • 深圳洲聚网站建设wordpress 泛解析
  • 五金东莞网站建设技术支持wordpress 添加模板
  • 网站申请专利春节网页设计素材
  • 进网站备案md风格的wordpress主题
  • 如何建站网站十大免费建站app