type
status
date
slug
summary
tags
category
password
icon

Android 的 Handler 机制

  • 本质:在某个指定的运⾏中的线程上执⾏代码
  • 思路:在接受任务的线程上执⾏循环判断
  • 基本实现:
    • Thread ⾥ while 循环检查
    • 加上 Looper(优势在于⾃定义 Thread 的代码可以少写很多):
    • 再加上 Handler(优势在于功能分拆,⽽且可以有多个 Handler)
  • Java 的 Handler 机制:
    • HandlerThread:具体的线程
    • Looper:负责循环、条件判断和任务执⾏
      • 在 loop 方法中会
    • Handler:负责任务的定制和线程间传递
      • Handler 构造方法中需要一个 Looper 成员变量
      • Handler 也能够接受 Message(会把 Handler 封装进 Message 中)转发给 Looper
    • Message:负责封装消息特征
      • 内部的 target 成员变量是一个 Handler,会在 Looper 的 loop 方法中被调用dispatchMessage()
💡
Android 中,通过 Looper 类中的 ThreadLocal 变量存储 Looper,每个线程在 run() 方法中先通过 Looper.prepare() 方法创建一个自己的 Looper(Main 线程是通过 Looper.prepareMainLooper() ),存储在 Looper 的 ThreadLocal 变量中,这样每个线程调用 ThreadLocal 变量获取到的都是自己的 Looper。而Looper 中存储了消息队列 MessageQueue,通过 Looper.loop() 方法去死循环遍历消息队列中的消息,并调用每个 Message 自己 Handler 的 dispatchMessage() 方法去执行消息
notion image
  • AsyncTask:
    • AsyncTask 的内存泄露
    • 众所周知的原因:AsyncTask 持有外部 Activity 的引⽤
    • 没提到的原因:执⾏中的线程不会被系统回收
    • Java 回收策略:没有被 GC Root 直接或间接持有引⽤的对象,会被回收 GC Root:
        1. 运⾏中的线程
        1. 静态对象
        1. 来⾃ native code 中的引⽤
    • 所以:
      • AsyncTask 的内存泄露,其他类型的线程⽅案(Thread、Executor、HandlerThread)⼀样都有,所以不要忽略它们,或者认为 AsyncTask ⽐别的⽅案更危险。并没有。
      • 就算是使⽤ AsyncTask,只要任务的时间不⻓(例如 10秒 之内),那就完全没必要做防⽌内存泄露的处理。

Service 和 IntentService

  • Service:后台任务的活动空间,并不会自动把内容放在后台线程,需要自己开线程切换到后台。适⽤场景:⾳乐播放器等
  • IntentService:将单个任务放在后台执行后⾃动关闭的 Service

Executor、AsyncTask、HandlerThead、IntentService 的选择

原则:哪个简单⽤哪个
  • 能⽤ Executor 就⽤ Executor
  • 需要⽤到「后台线程推送任务到 UI 线程」时,再考虑 AsyncTask 或者 Handler
  • HandlerThread 的使⽤场景:原本它设计的使⽤场景是「在已经运⾏的指定线程上执⾏代码」,但现实开发中,除了主线程之外,⼏乎没有这种需求,因为 HandlerThread 和 Executor 相⽐在实际应⽤中并没什么优势,反⽽⽤起来会麻烦⼀点。不过,这⼆者喜欢⽤谁就⽤谁吧。
  • IntentService:⾸先,它是⼀个 Service;另外,它在处理线程本身,没有⽐ Executor 有任何优势
 

关于 Executor 和 HandlerThread 的关闭

如果在界⾯组件⾥创建 Executor 或者 HandlerThread,记得要在关闭的时候(例如 Activity.onDestroy() )关闭 Executor 和 HandlerThread。
线程间通信多线程和线程同步
Loading...
shuouyang
shuouyang
android开发 ReactNative开发 小程序开发
最新发布
AOSP 环境搭建
2025-3-29
View 绘制流程-源码解析
2025-3-12
HTTP
2025-3-4
JVM 虚拟机
2025-2-28
蓝牙-BLE-基础
2025-2-28
从 OkHttp 的原理来看 HTTP
2025-2-19
公告
🎉热点信息🎉
--- 1 ---
Jet Brains 推出新的跨平台支持 Kotlin MultiPlatform
--- 2 ---
新的小巧便捷的依赖注入框架 Koin
--- 3 ---
新一代 API 查询语言 GraphQL