Android监听USB插拔的Intent广播多次触发出现ANR错误是什么原因?
USB插拔触发ANR的诱因分析
- 未正确处理子线程Looper生命周期
你在USB拔出的子线程中调用了Looper.prepare(),但执行完任务后既没有调用Looper.loop()也没有调用Looper.quit()释放资源。每个线程的Looper是线程局部独立实例,多次插拔会生成大量持有未销毁Looper的僵尸线程,无法被GC回收,造成严重内存泄漏,最终系统资源耗尽触发ANR。 - 阻塞队列操作存在无限阻塞风险
代码中调用的powerStatusQueue.put()、laserKeyStatusQueue.put()属于BlockingQueue的阻塞方法,如果队列已满,该方法会无限等待直到有空闲位置。如果消费队列的逻辑出现异常停止消费,多次插拔会导致大量子线程阻塞在put操作上,线程资源被占满后触发ANR。 - 多线程并发无同步锁,存在死锁风险
你直接在多个子线程中并发修改、访问MainActivity.eMRO_Backend等静态全局变量,没有加任何同步锁。频繁插拔时USB插入和拔出事件可能同时触发,一边尝试创建eMRO_Backend实例,一边尝试调用其shutDownThreads()方法,很容易触发死锁,一旦主线程需要访问这些被死锁占用的资源,就会触发ANR。 - 无节制创建新线程,CPU调度过载
每次插拔事件都会创建一个新的子线程,没有用线程池做复用和数量控制。短时间内频繁插拔会生成大量线程,CPU调度负载过高,系统无法及时响应应用的主线程操作,从而触发ANR。 - 潜在的上下文内存泄漏风险
插入事件中创建eMRO_Backend时传入了BroadcastReceiver的上下文,而eMRO_Backend实例被静态变量持有,会导致相关的Activity/Context无法被回收,多次插拔后内存占用持续升高,最终引发ANR。
内容的提问来源于stack exchange,提问作者aight101
相关产品推荐
相关产品推荐

