NsdManager不会停止服务发现

在我正在开发的Android应用程序中,我想使用NsdManager连接做零配置网络。

我设法运行网络服务发现并连接到所需的网络,但停止发现后NsdManager线程仍在运行。 这导致在几次屏幕旋转之后有许多NsdManager线程正在浏览连接的情况。

在此处输入图像描述

当任何网络可用时,设备会尝试多次同步,因此尽管停止服务发现,每个NsdManager仍处于活动状态。

贝娄是我的代码:

 package dtokarzewsk.nsdservicetest; import android.content.Context; import android.net.nsd.NsdManager; import android.net.nsd.NsdServiceInfo; import android.util.Log; import java.net.InetAddress; public class NsdTest { private static final String NSD_SERVICE_NAME = "TestService"; private static final String NSD_SERVICE_TYPE = "_http._tcp."; private int mPort; private InetAddress mHost; private Context mContext; private NsdManager mNsdManager; private android.net.nsd.NsdManager.DiscoveryListener mDiscoveryListener; private android.net.nsd.NsdManager.ResolveListener mResolveListener; public NsdTest(Context context) { mContext = context; } public void startListening() { initializeResolveListener(); initializeDiscoveryListener(); mNsdManager = (NsdManager) mContext.getSystemService(Context.NSD_SERVICE); mNsdManager.discoverServices(NSD_SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener); } public void stopListening() { mNsdManager.stopServiceDiscovery(mDiscoveryListener); } private void initializeResolveListener() { mResolveListener = new NsdManager.ResolveListener() { @Override public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) { Log.d("NSDService test","Resolve failed"); } @Override public void onServiceResolved(NsdServiceInfo serviceInfo) { NsdServiceInfo info = serviceInfo; Log.d("NSDService test","Resolve failed"); mHost = info.getHost(); mPort = info.getPort(); Log.d("NSDService test","Service resolved :" + mHost + ":" + mPort); } }; } private void initializeDiscoveryListener() { mDiscoveryListener = new NsdManager.DiscoveryListener() { @Override public void onStartDiscoveryFailed(String serviceType, int errorCode) { Log.d("NSDService test","Discovery failed"); } @Override public void onStopDiscoveryFailed(String serviceType, int errorCode) { Log.d("NSDService test","Stopping discovery failed"); } @Override public void onDiscoveryStarted(String serviceType) { Log.d("NSDService test","Discovery started"); } @Override public void onDiscoveryStopped(String serviceType) { Log.d("NSDService test","Discovery stopped"); } @Override public void onServiceFound(NsdServiceInfo serviceInfo) { NsdServiceInfo info = serviceInfo; Log.d("NSDService test","Service found: " + info.getServiceName()); if (info.getServiceName().equals(NSD_SERVICE_NAME)) mNsdManager.resolveService(info, mResolveListener); } @Override public void onServiceLost(NsdServiceInfo serviceInfo) { NsdServiceInfo info = serviceInfo; Log.d("NSDService test","Service lost: " + info.getServiceName()); } }; } } 

并在主要Activity

 private NsdTest mNsdTest; @Override protected void onResume() { super.onResume(); mNsdTest = new NsdTest(this); mNsdTest.startListening(); } @Override protected void onPause() { mNsdTest.stopListening(); super.onPause(); } 

我该如何解决这个问题?

    我目前的解决方案是使包含NsdManager(上例中的NsdTest)的类成为具有更改上下文的单例。

    它不会改变NSdManager线程即使在停止服务发现后仍在运行的事实,但至少在恢复应用程序后只有一个活动的NsdManager线程。

    也许这不是最优雅的方式,但对我来说已经足够了。

     public class NsdTest { private static NsdTest mInstance; private static final String NSD_SERVICE_NAME = "TestService"; private static final String NSD_SERVICE_TYPE = "_http._tcp."; private int mPort; private InetAddress mHost; private Context mContext; private NsdManager mNsdManager; private android.net.nsd.NsdManager.DiscoveryListener mDiscoveryListener; private android.net.nsd.NsdManager.ResolveListener mResolveListener; private static NsdTest mInstance; private NsdTest(Context context) { mContext = context; } public static NsdTest getInstance(Context context) { if (mInstance == null) { mInstance = new NsdTest(context); } else { mContext = context; } return mInstance; } ...} 

    如果有人知道更好的解决方案,请发布。

    原因是因为NsdManager.stopServiceDiscovery是异步的。 从文档中 ,您必须等待onDiscoveryStopped(String)才能使发现会话实际结束。

    您在发送异步请求后立即暂停可能意味着当您的应用程序在后台时,将被触发的回调“丢失”。 异步回调的习惯是不能很好地处理后台。