android源码怎么运行 android项目实例源码

Android消息机制实际上指的是Handler的消息机制。上述模型的解释:1.以Handler的sendMessage方法为例。发送消息时,它将被添加到MessageQueue messagequeue中。2.Looper负责遍历消息队列,将队列中的消息分发到相应的处理程序进行处理。3.在Handler的handleMessage方法中处理消...

Android消息机制实际上指的是Handler的消息机制。

上述模型的解释:

1.以Handler的sendMessage方法为例。发送消息时,它将被添加到MessageQueue messagequeue中。

2.Looper负责遍历消息队列,将队列中的消息分发到相应的处理程序进行处理。

3.在Handler的handleMessage方法中处理消息,完成消息的发送和处理过程。从图中可以看出,消息处理涉及到四个对象,分别是Handler、message、MessageQueue和Looper。

ThreadLocal是线程内的数据存储类,通过它可以将数据存储在指定的线程中。数据存储后,只有指定的线程可以获取存储的数据,其他线程无法获取数据。

让我们来看看ThreadLocal是如何存储数据的:

public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap ***p = getMap(t); if (***p != null) ***p.set(this, value); else createMap(t, value);}在源码里面我们可以看出 ThreadLocal在存储数据的时候,会先拿到当前线程,然后根据当前线程会拿到一个叫做ThreadLocalMap 的Map数组;

那么什么是ThreadLocalMap呢?

我们可以看到在CreateMap中创建了ThreadLocalMap,把我们当前的线程作为一个键,过去传递的值就是调用ThreadLocal.set(T)传递的值。

void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue);}

ThreadLocal如何获取数据?

public T get() { Thread t = Thread.currentThread(); ThreadLocalMap ***p = getMap(t);//会先根据当前线程找到对应的ThreadLocalMap,如果没有就创建 if (***p != null) { ThreadLocalMap.Entry e = ***p.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); }//如果ThreadLocalMap 就会去创建ThreadLocalMap private T setInitialValue() { T value = initialValue(); Thread t = Thread.currentThread(); ThreadLocalMap ***p = getMap(t); if (***p != null) ***p.set(this, value); else createMap(t, value); return value; }

通过上面的代码,我们可以看到ThreadLocal是如何保证数据存储后,只有指定的线程可以获取存储的数据,而其他线程是无法获取数据的。

我们如何确保Acticity的默认线程是主线程?

实际上,我们使用的线程是ActivityThread,而

***in(String[] args)方法里面我们可以看到下面代码 public static void ***in(String[] args) { Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); }

//在上面的代码中,我们可以看到创建ActivityThread的looper . prepare ***in looper();looper . loop();确保ActivityThread是主线程。

创建一个全局唯一的Looper对象和一个全局唯一的MessageQueue消息对象。

在活动中创建处理程序

消息发送

消息处理信息处理

消息阻塞和延迟

Looper的阻塞主要通过MessageQueue实现,在next()@MessageQuese阻塞,在enqueueMessage()@MessageQueue唤醒。Looper主要依靠native层,依靠epoll机制。

Message next() { int pendingIdleHandlerCount = -1; // -1 only during first iteration int nextPollTimeoutMillis = 0; for (;;) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCom***nds(); }//阻塞和延时,主要是next()中nativePollOnce(ptr, nextPollTimeoutMillis)调用naive方法操作管道 nativePollOnce(ptr, nextPollTimeoutMillis); } }

以及阻塞延迟,主要是因为next()中的NativePollence (PTR,nextPollTimeoutMillis)调用naive方法操作管道,nextPollTimeoutMillis决定是否阻塞。当NextPollTimeoutMillis为0时,表示没有阻塞;当它为-1时,表示阻塞直到它醒来;其他时候,意味着拖延。

醒来

主要参考enqueueMessage()@MessageQueue来唤醒。

boolean enqueueMessage(Message msg, long when) { //在这里唤醒阻塞的方法 if (needWake) { nativeWake(mPtr); } }

简单理解一下阻塞和唤醒是指当主线程的MessageQueue中没有消息时,在loop的queue.next()中的nativePollOnce()方法中阻塞。此时主线程会释放CPU资源,进入睡眠状态,直到下一条消息到来或者有事务。通过将数据写入管道的写入端,它唤醒主线程工作。这里使用的epoll机制是一种IO复用机制,可以同时监控多个描述符。当一个描述符准备好了(读或写),它会立即通知相应的程序进行读或写,本质上是同步I/O,即读写被阻塞。所以主线程大部分时间是休眠的,不会消耗大量的CPU资源。从阻塞到唤醒,消息交换

延迟入队

enqueueMessage()消息队列是指上面的代码按照规则(从小到大的时候)对消息对象池进行重新排序。这里有两种for无限循环退出的情况:第一种:p==null表示对象池中的最后一个已经运行,不需要回收。第二种方法:当下一个消息when小于上一个消息时,立即推出循环(不管对象池中的所有消息是否都被遍历)并重新排序。

本文来自呆到深处自然萌投稿,不代表舒华文档立场,如若转载,请注明出处:https://www.chinashuhua.cn/24/625533.html

打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
() 0
上一篇 07-08
下一篇 07-08

相关推荐

  • java项目打包成jar包 java项目实例源码

    包单击包。打包后上传到pagoda文件。部署Java部署命令:nohup Java-jar/Java/Jenkins . war –httpPort = 666 & ampnohup表示挂起不退出,进行后台运行模式我是nohup Java-jar/***/server/Tomcat/web apps/empdalymgforserve . war –httpPort = 8087 & amp此处的操

    2023-07-23 07:09:01
    461 0
  • TikTok出售不带源码的美国业务,买家或是甲骨文!

    腾讯新闻9月14日报道,在Tiktok母公司字节跳动出售Tiktok美国业务的交易中,该公司可能不会将用于构建抖音算法的代码交给美国买家。据报道,字节跳动已经将该公司的立场改变通知了投标人和美国当局。随着剥离抖音美国业务的最后期限临近,字节跳动急于完成出售。但在周二谈判

    2023-07-18 11:53:01
    1048 0
  • api管理系统php源码 Api 国内PHP开源接口框架

    最后一章开始了。在这一章,让我们来做这个API的基本结构。我们称之为“老赵API系统”。首先,我们要做的API系统是私有的,不是开源的,不会分发给其他人使用(当然你要大力推广,随便你)。其次,我故意漏了一个小点子,是我自己用的,也怕我的方法泄露后会有安全问题。姑且称

    2023-07-12 03:09:01
    115 0
  • android源码怎么运行 android项目实例源码

    Android消息机制实际上指的是Handler的消息机制。上述模型的解释:1.以Handler的sendMessage方法为例。发送消息时,它将被添加到MessageQueue messagequeue中。2.Looper负责遍历消息队列,将队列中的消息分发到相应的处理程序进行处理。3.在Handler的handleMessage方法中处理消

    2023-07-08 18:24:01
    563 0

评论列表

联系我们

在线咨询: QQ交谈

邮件:admin@qq.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信