首先,在 AOSP 问题跟踪器上有一个跟踪此问题的未解决问题。提交错误的人可以在所有 Android 4.x 版本中重现,但没有使用 5.x 进行测试。
术语的简要解释:
- NsdManager - Android 应用程序与之交互的类,用于注册其 NSD 服务并发现其他 NSD 服务。NsdManager 实际上只是一个与 NsdService 建立异步连接的 shell。
- NsdService (com.android.server.NsdService) - 隐藏的 Android 系统服务,可以有来自多个客户端的连接。为创建和管理 NSD 服务以及将事件传回客户端应用程序进行所有繁重的工作和记账。
- NSD 服务- NsdService 代表您创建的服务,用于通过网络宣传您的应用程序的存在。
我刚刚用 5.1 测试了这个问题,并且问题已得到修复(从源代码来看,修复似乎进入了 5.0)。我创建了一个简单的应用程序,它只注册一个 NsdService 并在发生任何值得注意的事情时记录下来,包括生命周期事件 onCreate、onResume、onPause 和 onDestroy。通过重新启动、启动我的应用程序,然后通过 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 何时终止并正确清理它。您可以通过查看此处的源代码来更深入地了解 NsdService 日志。
总结一下,我将回答提示中的问题:
- 对于 4.x,没有超时,它会一直保持到重新启动。对于 5.x,NsdService 在您的应用断开连接时关闭 NSD 服务。
- 没有办法保证 onDestroy() 被调用,这里有更深入的解释。通过 Android Studio 安装会在不调用它的情况下杀死正在运行的应用程序。看看通过 App Store 进行的更新是否以相同的方式或更优雅地关闭正在运行的应用程序会很有趣。
- 在 5.x 中不是问题,因为它会立即杀死它们。在 4.x 中,无法删除旧注册,因为您会立即失去注册监听器。