我在Android上使用Network Service Discover (NSD)在设备上通告REST服务器。我的REST服务器包装在android.app.Service的一个实例中。
在onCreate
中,我成功地启动了REST服务器并注册了我的NSD服务。我可以在网络中的其他设备上看到NSD服务名称(例如,我的服务)。
在我的onDestroy
中,我停止REST Server并取消注册NSD服务。
然而,似乎在开发过程中,当我推送我的应用程序的新实例时(通过Eclipse),不能保证服务的onDestroy
将被调用。这意味着我的服务仍然是播发的,下一次服务启动时,我最终得到了My service (1)、My Service (2)等。
我知道NSD会修改服务名称来创建一个唯一的实例。我的问题是:
onDestroy
被调用?这种情况是否类似于用户安装我的应用程序的更新时可能遇到的情况?也就是说,是否保证在正在运行的应用程序关闭时调用onDestroy
,以便该应用程序的新版本可以在我的应用程序中检测旧注册并将其删除?发布于 2015-08-11 13:09:53
首先,在AOSP问题跟踪器上有一个open issue tracking this problem。提交bug的人可以在所有Android 4.x版本中重现,但没有在5.x版本中进行测试。
以下是术语的简要说明:
我刚刚用5.1测试了这个问题,这个问题已经修复了(从源代码上看,这个修复已经进入了5.0)。我创建了一个简单的应用程序,当发生任何值得注意的事件时,包括生命周期事件onCreate、onResume、onPause和onDestroy,它只注册一个NsdService并记录日志。通过重启,启动我的应用程序,然后通过Android Studio重新安装,我得到了以下日志。
W/SimpleNsdActivity(14379): onCreate
D/NsdService( 3516): startMDnsDaemon
D/NsdService( 3516): New client listening to asynchronous messages
D/NsdService( 3516): New client, channel: com.android.internal.util.AsyncChannel
@3c114a11 messenger: android.os.Messenger@3213e776
D/NsdService( 3516): Register service
D/NsdService( 3516): registerService: 2 name: NsdTest, type: _http._tcp., host:
null, port: 1349
W/SimpleNsdActivity(14379): onResume
D/NsdService( 3516): Register 1 2
W/SimpleNsdActivity(14379): onServiceRegistered as NsdTest
D/NsdService( 3516): SERVICE_REGISTERED Raw: 606 2 "NsdTest"
D/NsdService( 3516): Client disconnected
D/NsdService( 3516): Terminating client-ID 1 global-ID 2 type 393225
D/NsdService( 3516): unregisterService: 2
D/NsdService( 3516): stopMDnsDaemon
W/SimpleNsdActivity(15729): onCreate
D/NsdService( 3516): startMDnsDaemon
D/NsdService( 3516): New client listening to asynchronous messages
D/NsdService( 3516): New client, channel: com.android.internal.util.AsyncChannel
@38bace07 messenger: android.os.Messenger@26d8cd5d
D/NsdService( 3516): Register service
D/NsdService( 3516): registerService: 3 name: NsdTest, type: _http._tcp., host:
null, port: 1349
D/NsdService( 3516): Register 1 3
W/SimpleNsdActivity(15729): onResume
D/NsdService( 3516): SERVICE_REGISTERED Raw: 606 3 "NsdTest"
W/SimpleNsdActivity(15729): onServiceRegistered as NsdTest
您可以看到,onPause()
和onDestroy()
都没有被调用,因此我的应用程序没有对NSD服务进行显式清理。NsdService正在检测到客户端的AsyncChannel何时终止,并正在正确地进行清理。通过查看源here,您可以更深入地了解NsdService日志。
综上所述,我将回答提示符中的问题:
发布于 2015-08-07 18:06:42
关于第2)和第3)点,您可以执行以下操作:
onCreate()
方法中,生成一个随机数或时间戳并保存到本地字段;这将是服务ID BroadcastReceiver
中注册一个自定义BroadcastReceiver
,它将在每个Service
创建时响应您的自定义动作Service
ID的广播作为额外参数Service
,将触发已注册的BroadcastReceiver
;现在将收到的ID与当前服务的ID进行比较,如果不同,则调用stopSelf()
这样,只有最后的Service
才能存活下来。
https://stackoverflow.com/questions/22586686
复制相似问题