在我目前正在开发的Android应用程序中,我想使用NsdManager连接do零配置网络。
我成功地运行了网络服务发现并连接到所需的网络,但是在停止发现之后,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();
}我怎样才能解决这个问题?
发布于 2015-05-03 00:00:00
我目前的解决方案是使包含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;
}
...}如果有人知道更好的解决方案,请张贴。
发布于 2015-05-03 01:13:59
原因是因为NsdManager.stopServiceDiscovery是异步的。在文档中,必须等待onDiscoveryStopped(String)才能真正结束发现会话。
在发送异步请求后立即暂停,可能意味着当应用程序处于后台时,将被触发的回调“丢失”。异步回调习惯于不很好地处理后台的情况。
https://stackoverflow.com/questions/29628181
复制相似问题