引言
Android线程通信以及各种线程池的选择,也是我项目开发的知识盲区,可能在做项目也没有考虑那么多,只是隐约知道 <<Alibaba Java Code Guidelines>> 对线程池的使用做了一定的规范,最近有朋友咨询我关于内存泄漏问题也是和线程不规范有关,所以其实了解Android线程通信原理和Handler机制对深入了解内存溢出和泄漏本质还是很有必要的,希望这次分享对大家有所帮助
线程间的交互
一个线程启动别的线程
- new Thread().start();
- Executor.execute();
一个线程终结另一个线程
- Thread.stop(): 强制结束,可能会造成不可预知错误
- Thread.interrupt(): 温和式结束,不终结,不强制
- interrupted() 和 isInterrupted(): 检查(和重置)中断状态
- InterruptedException:如果线程在等待时中断,或在中断状态等待,直接结束等待过程,因为 等待过程什么也不会做
- 而 interrupt() 的目的是为了让线程做完,收尾工作尽快终结,所以要跳出等待工作
Object.wait() 和 Object.notify() / notifyAll()
- 未达到目标时 wait
- 用 while 时循环检查
- 设置完成后 notifyAll()
- wait(),notify(),notifyAll()都需要放到同步代码块里面
Thread.join()
让另一个线程插在自己前面
Thread.yield()
暂时让出自己的时间给同优先级的线程
Android Handler 机制
本质:
在某个指定运行的线程中执行代码
思路:
在接受任务线程中执行判断
基本实现:
- Thread 里面 的 while 循环检查
- 加上 looper(自定义 Thread 的代码可以少写很多)
- 再加上 Handler (优势在于功能互拆,而且可以有多个 Handler)
Java 的 Handler 机制
- HandlerThread: 具体线程
- Looper: 负责循环,条件判断和任务执行
- Handler: 负责线程的定制和线程间的传递
AsyncTask
- AsyncTask 内存泄漏
-
众所周知的原因: AsyncTask 持 有外部 Activity的引用
-
没有提到的原因: 执行的线程没有被回收
-
Java 回收策略: 没有被 GC 或 Root 直接或间接引用对象会被回收
GC Root:
1. 运行中的线程 2. 静态对象 3. 来自 native code 中的引用
-
所以:
- AsyncTask 的内存泄漏,其他方案一样(Thread,Executor,HandlerThread)一样都有,所以不要忽略他们,或者认为 AsyncTask 比别的方案更危险.并没有
- 就算是使用 AsyncTask ,只要任务时间不长(例如: 10s 以内),那就完全没必要做防止内存泄漏处理呢
Service 和 IntentService
- Service: 后台任务的活动空间,使用场景: 音乐播放器等
- IntentService: 执行单个任务自动关闭 Service
Executor , AsyncTask, HandlerThead 和 IntentService 比较
原则: 哪个简单用哪个
- 能用Executor 就用 Executor
- 需要用到「后台线程推送任务到 UI线程」 时,再考虑用Handler 或 AsyncTask
- HandlerThread 的使用场景: 原本它设计的使用场景是「在已经运行的指定线程上执行代码」,但现实开发中,除了主线程几乎没有这种需求,因为 HandlerThread 和 Executor 相比实际应用中并没有实际优势,反而用起来会更麻烦点,不过这两者使用谁就用谁.
- IntentService:首先,他是一个Service;另外,它在处理线程本身,没有比Executor 有任何优势
关于 Executor 和 HandlerThread 的关闭
如果在界面组件里创建 Executor 或者 HandlerThread ,记得要在关闭的时候(例如: Activity.onDestroy())
关闭 Executor
@Override
protected void onDestroy(){
super.onDestroy();
executor.shutdown();
}
关闭 HandlerThread
@Override
protected void onDestroy() {
super.onDestroy();
handlerThread.quit();
// 这个其实就是停⽌止 Looper的循环
}
最后
如果你看到了这里,觉得文章写得不错就给个赞呗!欢迎大家评论讨论!如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足,定期免费分享技术干货。谢谢!