调试服务崩溃
我有一个音乐服务,当然在后台照顾音乐播放,还有一些其他的事情,比如通知需要进行的UI更改的活动,存储和恢复队列,获取歌曲记录通过光标,每当歌曲发生变化时,它都会在正在进行的通知中更新位图。调试服务崩溃
什么问题?服务崩溃几乎所有的时间用户试图做..几乎任何东西。例如,播放一首歌曲,然后打开一个游戏会使该服务崩溃,有时候在Chrome浏览器上点击浏览网页也会使其崩溃。
的一些细节:
1 -业务通过startService(new Intent(this, MyMusicService.class));
开始,但是当用户离开活动我打电话startForeground(mId, mNotification);
显示正在进行的通知,可轻松控制,也因为startForeground()
是intented的服务,应优先为这些由activityManager杀人将是破坏性的用户体验(如果服务被杀害音乐停止)
2 -我试图重现崩溃,而且做得不那么当它肯定会发生沉重的工作,如浏览铬(这将重现几乎50%的时间崩溃),和总是时,像做启动寺庙运行2. FYI,如果不做任何事情 - 只是在背景上播放音乐和闲置,播放将不会停止而不是,它的工作方式与其打算的一样。
3 -我用作测试设备的手机不是任何缓慢或低存储设备,它是Galaxy Nexus。
4 -我试图抓住一些多头,有时它只是说:
02-24 06:53:32.586: I/ActivityManager(387): Process com.deadpixels.light.player (pid 27720) has died.
没有任何其他消息,有时同样的消息是伴随着WINDEATH:
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}
我还注意到,几乎总是在碰撞发生时,很多其他服务“死亡”。我附上完整日志here。
5 -我试着用ACRA,以获取有关崩溃的更多信息,但即使一切似乎正确地安装,崩溃日志不被发送,或者只是没有任何反应了。我知道ACRA检测碰撞并启动:
02-24 06:53:37.719: D/ACRA(28293): ACRA is enabled for com.deadpixels.light.player, intializing...
02-24 06:53:37.742: D/ACRA(28293): Using default Mail Report Fields
02-24 06:53:37.742: D/ACRA(28293): Looking for error files in /data/data/com.deadpixels.light.player/files
02-24 06:53:37.742: W/ACRA(28293): com.deadpixels.light.player reports will be sent by email (if accepted by user).
但正在发送什么都没有,既没有给我邮寄地址设置,或在谷歌文档的形式。
不知道还有什么可以尝试,我希望得到一些好的想法,寻找什么。正如我所说,服务确实做了一些事情,据我所知,这不是那种资源丰富的,说实话,我甚至不确定是否与服务崩溃有关。
这里是gist的几个代码位发生在服务中,也是我设置的ACRA代码。还值得注意的是,我试图重现与其他音乐播放器崩溃的服务,我根本没有遇到这个问题。
感谢您的帮助!
看起来操作系统认为你的服务在用户离开你的活动后立即就在后台,尽管它是'前台'服务。
我会有些不同设计你MyMusicService
服务:
- 在
onCreate
准备MediaPlayer
。 - 在
onStart
或onStartCommand
执行您的服务,开始播放选定的/适当的声音文件。如果您希望音乐在后台继续播放,即使设备处于睡眠状态,也要获取部分wake_lock。返回START_STICKY
。 - 将通知添加到状态栏。 3在
onDestroy
,清理一切。
当音乐停止时,无论是通过用户交互还是歌曲结束时,都一定要删除通知并释放唤醒锁。
一个很好的教程可以在这里找到。 http://www.youtube.com/watch?v=mcb99u8Nlgs&list=PL14AA2548E3C96B50
更新后OP添加的意见/更新 '要点':
我看到的onReceive
你BroadcastReceiver
mReceiver
在服务访问数据库。这可能是问题。将其卸载到IntentService
:在onReceive
中,只需使用onReceive
收到的相同Intent
开始IntentService
。然后IntentService
可以做所有的实际工作,而不用担心任何可能的缓慢的数据库访问导致进程被终止。
如果在设备睡着时播放音乐仍然需要工作,请确保获得部分唤醒锁定(并且必要时请务必将其释放!)。
如果您提供了关于您的架构的更多信息,特别是您的活动和您的服务如何交互,它肯定会有所帮助。
狂野的猜测,当然,但对我来说,听起来好像你的服务有一个参考你的活动。只要您使用其他应用程序,您的活动就可能会被破坏。
有几个问题。
- 您的服务和您的活动是否在相同的过程中运行? (这会影响活动和服务之间的信息如何共享。)
- 您的活动类是否有任何服务试图访问的变量? (他们属于应用程序类,如果有的话)
是的,他们都运行在相同的过程。我试图做不同的过程,但是aidl界面让我疯狂。就访问而言,他们主要通过意图进行交流,例如,用户点击活动上的播放按钮,然后发送广播,服务捕捉并播放广播额外指定的歌曲。要回答你的第一个问题,不,服务不保留对活动的引用。 – 2013-03-04 13:23:52
我有同样的问题,你可以检查你的mId是否与你的通知的ID相同?还要检查它与0不同,因为它会将它与活动的id关联起来并与活动一起死亡。
编辑:另请检查您的代码不使用onHandle,但onStartCommand。
请检查你的代码,也许某个地方毁了你自己的过程,就像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!
我其实onStartCommand期间返回START_STICKY了。至于onCreate,我确实发起了这个球员,但是我还是不能打电话给准备,因为即使在音乐被要求播放之前这项服务已经开始了,因此我不知道我应该通过哪首歌的路径。另外,当歌曲播放时,我会添加状态栏通知,但我不确定您是否在发布的要点达到顶峰。不过,我会考虑购买一个我认为不需要的wakelock,因为在我没有使用手机的情况下,它可以在30分钟内播放BG音乐。 – 2013-02-26 23:11:15
在'gist'链接中,我没有看到任何'onStart'或'onStartCommand'实现,这就是为什么我问了:)如果您在服务的onCreate中调用'startForeground',部分唤醒锁定仅在您即使在设备睡着时也想玩。当设备没有睡着时,'startForeground'应该阻止了服务的被杀。您是否检查过您的服务广播接收器中的onReceive方法的实现?他们必须快速运行;如果没有,你的过程可能会被杀死。 – 2013-02-27 14:19:57
嗨,你是对的,我没有包括onStartCommand,我现在添加了,因为我更新了要点。此外,我仅在离开活动时(即,在回家或其他活动时)调用startForeground,并在恢复时调用stopForeground(true)。至于onReceive,不知道如何测试,看它是否快速运行。我在onReceive中添加了onReceive的几个位 – 2013-02-27 14:41:58