EventBus自己踩过的一些坑

EventBus采坑填坑——线程控制

前言

  我想现在对于Android工程师来说对EventBus并不会陌生,其使用非常简单只需三步1.定义事件、2.订阅事件、3.发送事件,今天笔者不再对其使用以及源码进行赘述因为网上遍地都是,今天主要来讲述一下我在使用过程遇到的坑:

  1.使用subscribe注解的方法只能使用public修饰:这个是比较低级的错误,但是刚开始使用的使用容易将注解的函数使用private修饰,这个只需要去看下源码很容易就能理解;

  2.第二个坑就是EventBus的线程模型了,我们知道EventBus3开始使用注解,订阅函数可以使用threadMode来切换线程,其threadMode共有四种:POSTING,MAIN,BACKGROUND,ASYNC。

  首先来说一下POSING:因为默认的就是这个模式,表示事件在哪个线程中发布出来的,事件订阅函数就会在这个线程中运行,也就是说发布事件和接收事件在同一个线程,所以订阅函数中不能有耗时任务;

  再来看MAIN:这个就比较好理解了,无论事件是在哪个线程发布出来的,该事件订阅方法都会在UI线程中执行,这个在Android中是非常有用的,因为在Android中只能在UI线程中更新UI,所有在此模式下的方法是不能执行耗时操作的;
  ASYNC:使用这个模式的订阅函数,那么无论事件在哪个线程发布,都会使用自己维护的线程池中的线程来执行;

  BACKGROUND是最容易犯错的模式,如果事件在UI线程中发布出来的,那么订阅函数就会在唯一的子线程中运行,如果事件本来就是在子线程中发布出来的,那么订阅函数直接在该子线程中执行,所以此处我们就要小心了,原本我们主观认为的这里会有一个线程池来处理消息,可事实并非如此,如果发布事件来自主线程,那么其底层只有一个唯一的子线程去处理订阅函数,这样处理可以保证事件顺序执行可以也带来一个额问题就是不能有耗时任务,这里的耗时任务仍然需要我们自己维护线程池或者其他的方式来处理,笔者就是在这里踩的坑,在这里简单的说下踩坑事件,笔者使用AudioRecord来处理录音而webRTC也需要使用录音功能所以笔者就使用EventBus来处理两者之间的冲突,就是WebRTC打开前先stop,release掉AudioRecord资源,WebRTC挂断后再继续AudioRecord的功能,可是由于发布事件来自主线程,而订阅事件中录音以及录音的分析是长时间耗时任务,所以订阅函数执行的时候长时间阻塞EventBus的那个唯一子线程,故而后面的事件就完全无法处理更无法停掉以及释放AudioRecord的资源,后来解决的办法就是在订阅事件中维护一个Handler使所有的stop,start事件在handler中顺序处理,而耗时的录音分析等逻辑在Rx线程中处理,这样一来可以避免二次订阅事件无法接受二来也能处理AudioRecord资源的start,stop顺序,避免多个线程操作AudioRecord资源。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值