广州有专做网站,小程序开发前景怎么样,世界十大搜索引擎排名,编程培训机构需要哪些证件笔者希望做一个系列#xff0c;整理 Android 基础技术#xff0c;本章是关于 Handler 为什么一个线程对应一个Looper#xff1f; 核心#xff1a;通过ThreadLocal保证 Looper.prepare的时候#xff0c;ThreadLocal.get如果不空报异常#xff1b;否则调用ThreadLocal.set,…笔者希望做一个系列整理 Android 基础技术本章是关于 Handler 为什么一个线程对应一个Looper 核心通过ThreadLocal保证 Looper.prepare的时候ThreadLocal.get如果不空报异常否则调用ThreadLocal.set, ThreadLocal.set 会调用当前线程Thread里的ThreadLocalmap put 键值对put 的键值对就是 Key ThreadLocal, Value Looper 线程里有TreadLocalMap的成员变量 Key ThreadLocal, Value Looper Looper 中有一个 static final 的成员变量就是 ThreadLocal意味着唯一性 Looper有final的成员MessageQueue 一个线程可以有多少个 Handler 可以有多个 Handler内存泄漏的原因 匿名内部类handler 默认持有外部类的activity的引用。 并且Handler.enqueMessage的时候 msg.target handler message持有了handler, 引用链msg-handler-activity或者fragment 为什么主线程可以New handler; 子线程new handler需要做什么 子线程 必须 Looper.prepare Looper.loop 主线程 在ActivityThread.main方法里 帮你Looper.prepareMainLoop和Looper.loop 子线程中维护的looper消息队列无消息的时候处理方案是什么有什么作用 主线程会阻塞主线程不能调用quit 子线程没有消息的时候需要调用quit 这个quit作用唤醒线程 调用 quit 后messagequeue返回null 退出loop 消息的睡眠的唤醒机制是怎样的 生产者消费者模式 入队满的时候 阻塞 这个handler没有限制满的情况 出队空的时候 阻塞 java的多线程里有阻塞队列但是handler不是这样没有限制消息个数。 nativePollOnce 到了C层 会调用epoll_wait等待 阻塞整个线程, CPU释放 nativeWake 到了C层调用 epoll 的wake 多个handler往messagequeue发送消息 如何保证线程安全 通过两点来保证线程安全 一个线程只有一个messageQueue 使用synchronized 内置锁加锁和释放是JVM帮我们完成的锁的是MessageQueue 对象里面的所有函数/代码块都受限 子线程发送消息为什么能在主线程接收也就是线程是如何切换的 子线程thread: handler.sendMessage-MessageQueue.enqueMessage. MessageQueue是没有线程之说。他是一个数据结构内存共享。 主线程loop 轮询MessageQueue。这个时候MessageQueue.next在主线程执行。 ThreadLocal整个系统只有一个吗 会不会有矛盾 线程1-ThreadLocalMap1 唯一的ThreadLocal-looper1 线程2-ThreadLocalMap2 唯一的ThreadLocal-looper2 一个线程对应一个Looper一个Looper 对应一个 ThreadLocal 调整系统时间对延时消息有没影响 Handler的延迟消息计算是通过SystemClock类来计算跟系统时间没有任何关系这是根据Handler自启动以来非睡眠正常运行时间的毫秒数和代码指定的postDelayed的时间来计算的。 我们使用Message如何创建 通过obtainMessage 享元设计模式 内存复用android中使用非常广泛 如recyclerView 维持一个消息池防止内存碎片-内存抖动-OOM 消息释放后插入到队列头部重置队头为这个消息节点 Looper死循环为什么不会导致卡死 和anr无关。 为什么msg 阻塞不会导致anr 这个阻塞是指线程没有事情做了释放cpu休眠 什么是同步屏障 msg.targetnull 的消息就是同步屏障 同步屏障的场景刷新UI ViewRootImpl scheduleTraversals--- postSyncBarrier 在对头插入节点 同步屏障的删除ViewRootImpl unScheduleTraversals----removeSyncBarrier 删除屏障的节点 同步屏障就是把同步消息给屏障掉了 然后优先执行异步消息setAsynchrious标志 messageQueue.next的时候 先判断 如果msg.targetnull 轮询消息队列直到找到一个异步消息为止执行这个异步消息。 setAsynchrioustrue)这个标志。 刷新UI 使用了同步屏障就是为了保证及时执行消息如果保证不了16ms 刷新一次 会导致掉帧。 我们平时发送到消息是同步消息 同步屏障的作用是什么 我们向主线程发送了一个UI绘制操作Message而此时消息队列中的消息非常多那么这个Message的处理可能会得到延迟绘制不及时造成界面卡顿。同步屏障机制的作用是让这个绘制消息得以越过其他的消息优先被执行。