我有一个音乐服务,在后台处理音乐播放,还有一些其他的事情,比如通知需要进行的UI更改活动,存储和恢复队列,通过游标获取歌曲记录,每当歌曲改变时,它会负责更新正在进行的通知中的位图。
问题是什么?服务崩溃几乎所有用户都试图做的事情......几乎所有其他事情。例如,播放一首歌,然后打开一个游戏会破坏服务,有时像浏览网页上的光线也会让它崩溃。
一些细节:
1 - 该服务是通过startService(new Intent(this, MyMusicService.class));
启动的,但当用户离开活动时,我致电startForeground(mId, mNotification);
以显示提供简单控制的持续通知,同时也因为{{1}因为activityManager对这些服务的杀戮会对用户体验造成破坏(如果服务被杀死就会停止音乐),那么这些服务应该被优先考虑。
2 - 我试图重现崩溃,当你没有那么繁重的工作时,肯定会发生这种情况,例如浏览chrome(这会在几乎50%的时间内重现崩溃),并且开始运行时,总是 2。如果没有做任何事情 - 仅仅在后台播放音乐并闲置,播放将不停止,并且它的工作方式就是它的意图。
3 - 我用作测试设备的手机绝对不是慢速或低内存设备,而是Galaxy Nexus。
4 - 我尝试过多次阅读,有时只是说:
startForeground()
没有任何其他消息,有时同一条消息伴随着WINDEATH:
02-24 06:53:32.586: I/ActivityManager(387): Process com.deadpixels.light.player (pid 27720) has died.
我还注意到,几乎总是在崩溃发生时,许多其他服务“死”。我附上完整的日志here。
5 - 我尝试使用ACRA获取有关崩溃的更多信息,但即使一切似乎都设置正确,崩溃后日志也没有发送,或者没有任何反应。我知道ACRA检测到崩溃并开始:
02-24 06:53:32.586: W/ActivityManager(387): Scheduling restart of crashed service com.deadpixels.light.player/.service.MyMusicService in 5000ms
02-24 06:53:32.602: W/InputDispatcher(387): channel '418d09c8 com.deadpixels.light.player/com.deadpixels.light.player.HomeActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x9
02-24 06:53:32.602: E/InputDispatcher(387): channel '418d09c8 com.deadpixels.light.player/com.deadpixels.light.player.HomeActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
02-24 06:53:32.602: W/InputDispatcher(387): Attempted to unregister already unregistered input channel '418d09c8 com.deadpixels.light.player/com.deadpixels.light.player.HomeActivity (server)'
02-24 06:53:32.602: I/WindowState(387): WIN DEATH: Window{418d09c8 u0 com.deadpixels.light.player/com.deadpixels.light.player.HomeActivity}
但是没有发送任何内容,也没有发送到我设置的mailto或Google文档中的表单。
不确定还有什么可以尝试的,我希望得到一些关于要寻找什么的好主意。正如我所说,该服务确实做了一些事情,据我所知,这并不是那种资源丰富的,而且说实话,我甚至不确定它是否与崩溃的服务有关。
这是服务中发生的几个代码位的gist,以及我设置的ACRA代码。值得注意的是,我试图重现与其他音乐播放器崩溃的服务,我根本没有遇到这个问题。
感谢您的帮助!
答案 0 :(得分:3)
操作系统似乎认为只要用户离开您的活动,您的服务就会在后台运行,尽管它是一个前景'服务。
我会设计你的MyMusicService
服务有点不同:
onCreate
准备MediaPlayer
。 onStart
或onStartCommand
实施中,开始播放所选/适当的声音文件。如果您希望音乐在后台继续播放,即使设备处于睡眠状态,也会获取部分wake_lock。返回START_STICKY
。onDestroy
中,清理所有内容。当音乐停止时,无论是通过用户互动还是歌曲结束,请务必删除通知并释放唤醒锁定。
这里有一个很好的教程。 http://www.youtube.com/watch?v=mcb99u8Nlgs&list=PL14AA2548E3C96B50
OP添加评论后更新/更新' gist'
我看到您服务中onReceive
BroadcastReceiver
的{{1}}访问数据库。这可能是个问题。将其卸载到mReceiver
:在IntentService
中,只需使用与onReceive
收到的IntentService
相同的Intent
开始onReceive
。然后IntentService
可以完成所有实际工作,而不用担心任何可能的数据库访问速度慢导致进程被终止。
如果在设备处于睡眠状态时仍然需要播放音乐,请务必获取部分唤醒锁定(并确保在必要时将其释放!)。
答案 1 :(得分:2)
我遇到了同样的问题,你能检查一下你的mId是否与你的通知ID相同吗?同时检查它是否不同于0,因为它会将它与活动的id相关联并与活动一起消失。
编辑:同时检查您的代码是否使用onHandle而不是onStartCommand。
答案 2 :(得分:0)
如果您提供了有关您的架构的更多信息,特别是您的活动和服务如何互动,那肯定会有所帮助。
当然疯狂猜测,但对我而言,听起来好像您的服务引用了您的活动。一旦您使用其他应用,您的活动很可能会被销毁。
几个问题。
答案 3 :(得分:0)
请检查您的代码,也许是您自己破坏过程的地方,例如System.exit(0);
,如果您这样做,那么会有日志
channel '418d09c8
com.deadpixels.light.player/com.deadpixels.light.player.HomeActivity(server)'
~ Consumer closed input channel or an error occurred. events=0x902-24 06:53:32.602:
E/InputDispatcher(387): channel '418d09c8
com.deadpixels.light.player/com.deadpixels.light.player.HomeActivity (server)'
~ Channel is unrecoverably broken and will be disposed!