Android高手进阶(Android线程通信 | Handler | 线程池选择)

引言

  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 中的引用
      

所以:

  1. ​​​​​​​AsyncTask 的内存泄漏,其他方案一样(Thread,Executor,HandlerThread)一样都有,所以不要忽略他们,或者认为 AsyncTask 比别的方案更危险.并没有
  2. 就算是使用 AsyncTask ,只要任务时间不长(例如: 10s 以内),那就完全没必要做防止内存泄漏处理呢

Service 和 IntentService

  • Service: 后台任务的活动空间,使用场景: 音乐播放器等
  • IntentService: 执行单个任务自动关闭 Service

Executor , AsyncTask, HandlerThead 和 IntentService 比较

原则: 哪个简单用哪个

  • 能用Executor 就用 Executor
  • 需要用到「后台线程推送任务到 UI线程」 时,再考虑用HandlerAsyncTask
  • HandlerThread 的使用场景: 原本它设计的使用场景是「在已经运行的指定线程上执行代码」,但现实开发中,除了主线程几乎没有这种需求,因为 HandlerThreadExecutor 相比实际应用中并没有实际优势,反而用起来会更麻烦点,不过这两者使用谁就用谁.
  • 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的循环

}

最后

如果你看到了这里,觉得文章写得不错就给个赞呗!欢迎大家评论讨论!如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足,定期免费分享技术干货。谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值