首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Android网络服务发现“超时”?

Android网络服务发现“超时”?
EN

Stack Overflow用户
提问于 2014-03-23 11:25:52
回答 2查看 2K关注 0票数 20

我在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会修改服务名称来创建一个唯一的实例。我的问题是:

  1. 如果播发的服务不再存在,预计会有多长时间被删除?
  2. 当我推送应用程序的新实例时,有没有办法确保我的onDestroy被调用?这种情况是否类似于用户安装我的应用程序的更新时可能遇到的情况?也就是说,是否保证在正在运行的应用程序关闭时调用onDestroy,以便该应用程序的新版本可以在我的应用程序中检测旧注册并将其删除?
EN

回答 2

Stack Overflow用户

发布于 2015-08-11 13:09:53

首先,在AOSP问题跟踪器上有一个open issue tracking this problem。提交bug的人可以在所有Android 4.x版本中重现,但没有在5.x版本中进行测试。

以下是术语的简要说明:

  • NsdManager - Android应用程序接口的类,用于注册其NSD服务和发现其他NSD服务。NsdManager实际上只是一个外壳,它与隐藏在NsdService.
  • NsdService(com.android.server.NsdService)中的安卓系统服务建立了异步连接,可以从多个客户端进行连接。完成创建和管理NSD服务以及将事件传回客户端applications.
  • NSD服务的所有繁重工作和记账- NsdService代表您创建的服务,用于通过网络通告您的应用程序的存在。

我刚刚用5.1测试了这个问题,这个问题已经修复了(从源代码上看,这个修复已经进入了5.0)。我创建了一个简单的应用程序,当发生任何值得注意的事件时,包括生命周期事件onCreate、onResume、onPause和onDestroy,它只注册一个NsdService并记录日志。通过重启,启动我的应用程序,然后通过Android Studio重新安装,我得到了以下日志。

代码语言:javascript
复制
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日志。

综上所述,我将回答提示符中的问题:

  1. For 4.x没有超时,它将一直保持到重新启动。对于5.x,当你的应用程序disconnects.
  2. There不能保证调用onDestroy()时,NsdService会关闭NSD服务,更深层次的解释是here。通过Android Studio安装,在不调用的情况下终止正在运行的应用程序。看看通过应用程序商店的更新是以同样的方式运行还是更优雅地关闭正在运行的应用程序会很有趣。
  3. 在5.x中不是问题,因为它会立即杀死它们。在4.x中,没有办法删除旧的注册,因为您会立即失去注册侦听器。
票数 6
EN

Stack Overflow用户

发布于 2015-08-07 18:06:42

关于第2)和第3)点,您可以执行以下操作:

  • 在您的服务的onCreate()方法中,生成一个随机数或时间戳并保存到本地字段;这将是服务ID
  • 在您的BroadcastReceiver中注册一个自定义BroadcastReceiver,它将在每个Service创建时响应您的自定义动作
  • ,发送带有您的自定义动作和您当前的Service ID的广播作为额外参数
  • 对于每个活动的Service,将触发已注册的BroadcastReceiver;现在将收到的ID与当前服务的ID进行比较,如果不同,则调用stopSelf()

这样,只有最后的Service才能存活下来。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22586686

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档