Update sample NSD app to work reliably with current Android
Change the management of NSD Listener objects to one which ensures that each Listener will be used for only one NSD service request at a time (as the APIs were intended to function). Listeners are now allocated in a "lazy" on-demand way, rather than having one Listener of each type allocated at application startup time. When the Register or Discover button is clicked, any existing Listener request of that type will be canceled and the Listener discarded (avoiding the need to wait until the Listener callback has been completed), and a new Listener will be allocated. Moves code around in the application-lifecycle callbacks to reflect the current Android lifecycle. Doing important things like unregistering NSD services should not be done in the onDestroy() callback, as there is no guarantee that the app won't be killed before this callback is invoked. This can lead to "zombie" NSD registrations in KitKat. Adds additional lifecycle logging. Pass 2 - fix typo, clean up trailing whitespace Pass 3 - fix onStart/onRestart mismatch Bug: 13512512 Change-Id: Ic164110759204b27d8a14376777b593ebe1865fa
This commit is contained in:
@@ -52,7 +52,9 @@ public class ChatConnection {
|
||||
|
||||
public void tearDown() {
|
||||
mChatServer.tearDown();
|
||||
mChatClient.tearDown();
|
||||
if (mChatClient != null) {
|
||||
mChatClient.tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
public void connectToServer(InetAddress address, int port) {
|
||||
|
||||
@@ -43,6 +43,7 @@ public class NsdChatActivity extends Activity {
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Log.d(TAG, "Creating chat activity");
|
||||
setContentView(R.layout.main);
|
||||
mStatusView = (TextView) findViewById(R.id.status);
|
||||
|
||||
@@ -54,11 +55,6 @@ public class NsdChatActivity extends Activity {
|
||||
}
|
||||
};
|
||||
|
||||
mConnection = new ChatConnection(mUpdateHandler);
|
||||
|
||||
mNsdHelper = new NsdHelper(this);
|
||||
mNsdHelper.initializeNsd();
|
||||
|
||||
}
|
||||
|
||||
public void clickAdvertise(View v) {
|
||||
@@ -100,8 +96,20 @@ public class NsdChatActivity extends Activity {
|
||||
mStatusView.append("\n" + line);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
Log.d(TAG, "Starting.");
|
||||
mConnection = new ChatConnection(mUpdateHandler);
|
||||
|
||||
mNsdHelper = new NsdHelper(this);
|
||||
mNsdHelper.initializeNsd();
|
||||
super.onStart();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
Log.d(TAG, "Pausing.");
|
||||
if (mNsdHelper != null) {
|
||||
mNsdHelper.stopDiscovery();
|
||||
}
|
||||
@@ -110,16 +118,37 @@ public class NsdChatActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
Log.d(TAG, "Resuming.");
|
||||
super.onResume();
|
||||
if (mNsdHelper != null) {
|
||||
mNsdHelper.discoverServices();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// For KitKat and earlier releases, it is necessary to remove the
|
||||
// service registration when the application is stopped. There's
|
||||
// no guarantee that the onDestroy() method will be called (we're
|
||||
// killable after onStop() returns) and the NSD service won't remove
|
||||
// the registration for us if we're killed.
|
||||
|
||||
// In L and later, NsdService will automatically unregister us when
|
||||
// our connection goes away when we're killed, so this step is
|
||||
// optional (but recommended).
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
protected void onStop() {
|
||||
Log.d(TAG, "Being stopped.");
|
||||
mNsdHelper.tearDown();
|
||||
mConnection.tearDown();
|
||||
mNsdHelper = null;
|
||||
mConnection = null;
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
Log.d(TAG, "Being destroyed.");
|
||||
super.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,6 @@ public class NsdHelper {
|
||||
|
||||
public void initializeNsd() {
|
||||
initializeResolveListener();
|
||||
initializeDiscoveryListener();
|
||||
initializeRegistrationListener();
|
||||
|
||||
//mNsdManager.init(mContext.getMainLooper(), this);
|
||||
|
||||
@@ -87,13 +85,11 @@ public class NsdHelper {
|
||||
@Override
|
||||
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
|
||||
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
|
||||
mNsdManager.stopServiceDiscovery(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
|
||||
Log.e(TAG, "Discovery failed: Error code:" + errorCode);
|
||||
mNsdManager.stopServiceDiscovery(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -125,24 +121,30 @@ public class NsdHelper {
|
||||
@Override
|
||||
public void onServiceRegistered(NsdServiceInfo NsdServiceInfo) {
|
||||
mServiceName = NsdServiceInfo.getServiceName();
|
||||
Log.d(TAG, "Service registered: " + mServiceName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRegistrationFailed(NsdServiceInfo arg0, int arg1) {
|
||||
Log.d(TAG, "Service registration failed: " + arg1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceUnregistered(NsdServiceInfo arg0) {
|
||||
Log.d(TAG, "Service unregistered: " + arg0.getServiceName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
|
||||
Log.d(TAG, "Service unregistration failed: " + errorCode);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
public void registerService(int port) {
|
||||
tearDown(); // Cancel any previous registration request
|
||||
initializeRegistrationListener();
|
||||
NsdServiceInfo serviceInfo = new NsdServiceInfo();
|
||||
serviceInfo.setPort(port);
|
||||
serviceInfo.setServiceName(mServiceName);
|
||||
@@ -154,12 +156,20 @@ public class NsdHelper {
|
||||
}
|
||||
|
||||
public void discoverServices() {
|
||||
stopDiscovery(); // Cancel any existing discovery request
|
||||
initializeDiscoveryListener();
|
||||
mNsdManager.discoverServices(
|
||||
SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
|
||||
}
|
||||
|
||||
public void stopDiscovery() {
|
||||
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
|
||||
if (mDiscoveryListener != null) {
|
||||
try {
|
||||
mNsdManager.stopServiceDiscovery(mDiscoveryListener);
|
||||
} finally {
|
||||
}
|
||||
mDiscoveryListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
public NsdServiceInfo getChosenServiceInfo() {
|
||||
@@ -167,6 +177,12 @@ public class NsdHelper {
|
||||
}
|
||||
|
||||
public void tearDown() {
|
||||
mNsdManager.unregisterService(mRegistrationListener);
|
||||
if (mRegistrationListener != null) {
|
||||
try {
|
||||
mNsdManager.unregisterService(mRegistrationListener);
|
||||
} finally {
|
||||
}
|
||||
mRegistrationListener = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user