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

Android消息机制其实指的就是Handler的消息机制。以上模型的解释:1.以Handler的sendMessage方法为例,当发送一个消息后,会将此消息加入消息队列MessageQueue中。2.Looper负责去遍历消息队列并且将队列中的

Android消息机制其实指的就是Handler的消息机制。

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

以上模型的解释:

1.以Handler的sendMessage方法为例,当发送一个消息后,会将此消息加入消息队列MessageQueue中。

2.Looper负责去遍历消息队列并且将队列中的消息分发给对应的Handler进行处理。

3.在Handler的handleMessage方法中处理该消息,这就完成了一个消息的发送和处理过程。 这里从图中可以看到参与消息处理有四个对象,它们分别是 Handler, Message, MessageQueue,Looper。

ThreadLocal 是一个线程内部的数据存储类,通过它可以在指定的线程中存储数据,数据存储以后,只有再指定线程中可以获取到存储的数据,对于其他线程来说则无法获取到数据。

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

public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}

在源码里面我们可以看出 ThreadLocal在存储数据的时候,会先拿到当前线程,然后根据当前线程会拿到一个叫做ThreadLocalMap 的Map数组;

那么ThreadLocalMap 又是什么呢?

我们可以看到在CreateMap 里面是创建了ThreadLocalMap ,并且把我们当前线程当作Key,传递过去的 Value就是我们在调用ThreadLocal.set(T)传过来的值

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

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

ThreadLocal是如何获取数据的

public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
//会先根据当前线程找到对应的ThreadLocalMap,如果没有就创建
if (map != null) {
ThreadLocalMap.Entry e = map.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 map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
return value;
}

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

通过以上代码我们可以看出ThreadLocal是如何保证数据存储以后,只有再指定线程中可以获取到存储的数据,对于其他线程来说则无法获取到数据的了。

我们如何保证Acticity的默认线程是主线程的呢

在Acticity 中我们用到的线程是ActivityThread这个线程,在这个线程的

main(String[] args)方法里面我们可以看到下面代码

public static void main(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.prepareMainLooper(); Looper.loop(); 保证了 ActivityThread为主线程。

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

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

Activity中创建Handler

消息发送

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

消息处理

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

消息阻塞和延时

Looper 的阻塞主要是靠 MessageQueue 来实现的,在next()@MessageQuese 进行阻塞,在 enqueueMessage()@MessageQueue 进行唤醒。主要依赖 native 层的 Looper 依靠 epoll 机制进行的。

Message next() {

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

}
}android项目实例源码(android源码怎么运行)

阻塞和延时,主要是next()中nativePollOnce(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资源进入休眠状态,直到下个消息到达或者有事务发生,通过往pipe管道写端写入数据来唤醒主线程工作。 这里采用的epoll机制,是一种IO多路复用机制,可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立刻通知相应程序进行读或写操作,本质同步I/O,即读写是阻塞的。 所以说,主线程大多数时候都是处于休眠状态,并不会消耗大量CPU资源。 从阻塞到唤醒,消息切换

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

延时入队

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

主要指enqueueMessage()消息入列是,上图代码对message对象池的重新排序,遵循规则(when从小到大)。 此处for死循环退出情况分两种 第一种:p==null表示对象池中已经运行到了最后一个,无需再循环。 第二种:碰到下一个消息when小于前一个,立马推出循环(不管对象池中所有message是否遍历完),进行重新排序。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请发送邮件至 55@qq.com 举报,一经查实,本站将立刻删除。转转请注明出处:https://www.szhjjp.com/n/31054.html

(0)
新劵
上一篇 2021-09-28
下一篇 2021-09-28

相关推荐

  • 兆瓦时等于多少千瓦时(千瓦时和万千瓦时怎么换算)

    若要罗列世界上最适合安装太阳能电池板的地方,太平洋上的许多岛屿绝对名列前茅。由于没有天然气输送管道也没有运送煤炭的铁路,像夏威夷考艾岛(Kauai)这样的岛屿过去只能靠航运柴油燃料来进行发电。近年来,越来越多的岛上居民和企业开始安装太阳能面板,不过

    2021-10-14
    0
  • 沧浪亭记原文及翻译注释(沧浪亭记归有光原文及翻译)

    本文选自《震川先生集》卷十五。沧浪亭,是苏州市的四大古名园之一。它原是五代广陵王钱元璙的池馆,又说是五代末中吴军节度使孙承祐的别墅。到北宋时,诗人苏舜钦购得,并临水筑亭,题为“沧浪亭”,园也因亭而得名。后来又屡易其主。南宋初为抗金名将韩世忠

    2021-11-30
    0
  • 流转税主要包括哪四个税种(流转税包括哪些)

    企业成立后会涉及哪些税?1、流转税増值税消费税、关税等;我国税收体系2、所得税:企业所得税、个人所得税等;3.资源税:资源税、城镇土地使用税、土地增值税等4、财产税:房产税、车辆购置税、船舶吨税;5.行为税:印花税、车船税、城市维护建设税等6.其他税…

    2022-01-18
    0
  • 江苏哪些城市禁摩(哪些城市禁摩)

    本文约有3000字,阅读时长约3-4分钟,精选几个关于摩托车的常见问题来回答:经常有头条的朋友私信问我1.摩托车能上高速吗?2.禁摩的地区有哪些?3.新手适合骑什么车?4.川崎H2能不能上路?5.川崎H2到底多少钱?为解答以上几个常见的问题,特写此…

    2022-01-18 随笔
    0
  • 劳动仲裁前置的范围(劳动仲裁前置是什么意思)

    我国劳动用工纠纷,实行劳动仲裁前置。当劳动者与公司发生劳动纠纷时,劳动者需要先通过劳动局下设的“劳动人事争议仲裁委员会”劳动仲裁,劳动者与公司对劳动仲裁的结果不服的,才可以向法院提起民事诉讼,这就是我们经常说的“劳动仲裁前置”。其中,有一

    2021-12-13
    0
  • win10彻底永久关闭自动更新(win10系统如何关闭自动更新)

    win10的自动更新可谓是非常顽固,很多用户在网上试了各种关闭win10自动更新的方法,刚开始看着好像是关闭更新了,可没过多久系统就又开始自动更新了。今天电脑配置网就来教大家如何彻底关闭win10自动更新,该方法亲测有效。我是1月8号装的win10

    2021-09-28 随笔
    0

发表回复

登录后才能评论