从Service向Activity传数据时触发空指针异常的原因排查
触发NullPointerException的直接原因是:当广播接收器sReceiver调用listener.OnNotify(data)时,listener引用的值为null,具体场景如下:
广播事件在listener初始化前触发
你的代码逻辑是先绑定服务、调用service.attach(this)给sReceiver设置listener,再调用startService()注册广播接收器。但如果服务已经提前启动(比如系统通过START_STICKY重启服务),此时广播接收器已经完成注册,而Activity还未完成绑定流程、未设置listener,当BATTERY_LOW广播触发时,sReceiver中的listener还未被赋值,自然会抛出空指针异常。detach方法未清空listener引用
你的detach()方法是空实现,当Activity因配置变更(如屏幕旋转)或后台销毁时调用service.detach(),但并未清空sReceiver中的listener。如果之后服务仍在运行且收到广播,此时listener引用的旧Activity实例可能已被系统回收变为null,调用OnNotify()就会触发错误。广播接收器的生命周期与listener绑定不同步
你的sReceiver作为BroadcastReceiver,推测你实际实现了onReceive()方法并在其中调用OnNotify(),但当前的注册逻辑(在onStartCommand()中注册)无法保证接收器被激活时,listener已经完成绑定,两者生命周期不匹配导致空指针。
- 完善
detach()方法,清空listener并注销广播接收器:public void detach() { synchronized (this) { unregisterReceiver(receiver); receiver.setListener(null); } } - 调整广播注册时机,确保listener设置完成后再注册接收器:将
registerReceiver()移至attach()方法中,避免无listener的接收器被激活。 - 移除
onStartCommand()中的广播注册逻辑,让广播接收器的生命周期与Activity的绑定状态强关联。
内容的提问来源于stack exchange,提问作者Dinamo

