First of all, there is an open issue tracking this problem on the AOSP issue tracker. The person who filed the bug could repro in all Android 4.x versions but did not test with 5.x.
A brief explanation of terms:
- NsdManager - the class that Android applications interface with to register their NSD service and discover other NSD services. NsdManager is really just a shell that establishes an asynchronous connection with NsdService.
- NsdService(com.android.server.NsdService) - hidden Android system service that can have connections from multiple clients. Does all the heavy lifting and book-keeping for creating and managing NSD service and communicating events back to client applications.
- NSD service - the service that NsdService creates on your behalf that advertises your app's presence over the network.
I just tested this issue with 5.1 and the issue is fixed(from the source it looks like the fix went into 5.0). I created a simple application that just registers an NsdService and logs when anything of note happens, including lifecycle events onCreate, onResume, onPause, and onDestroy. I got the following logs by rebooting, starting my application, and then reinstalling via 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
You can see that neither onPause()
nor onDestroy()
were called and thus my application did no explicit cleanup for the NSD service. NsdService is detecting when the AsyncChannel to the client is terminated and is cleaning it up properly. You can get a deeper understanding of the NsdService logs by looking at the source here.
Summing it all up, I'll respond to the questions from the prompt:
- For 4.x there is no timeout, it will stay up until reboot. For 5.x NsdService shuts down the NSD service when your app disconnects.
- There is no way to guarantee onDestroy() is called, a deeper explanation here. Installation via Android Studio killing the running application without it being called. Would be interesting to see if updates via the App Store behave the same way or more gracefully shut down the running app.
- Not a problem in 5.x since it kills them right away. In 4.x, there's no way to remove old registrations since you immediately lose the registration listener.
onDestroy
is being called, try using thestopService
method. – BirthstoneonDestroy
won't be called if/when the user updates the version? – Topsail