问题描述
在我目前正在开发的Android
应用程序中,我想使用NsdManager
连接进行零配置网络.
In Android
app that I'm currently developing, I want to connect do zero-config networks using NsdManager
.
我设法运行网络服务发现并连接到所需的网络,但是在停止发现之后,NsdManager
线程仍在运行.导致这种情况的情况是,在几次屏幕旋转之后,有许多NsdManager
线程正在浏览连接.
I managed to run network service discovery and connect to the desired network, but after stopping discovery NsdManager
thread is still running. This leads to the situation when after a few screen rotations there are many NsdManager
threads that are browsing for a connection.
任何网络可用时,设备都会尝试进行多次同步,因此尽管停止了服务发现,每个NsdManager
仍处于活动状态.
When any network is available, device tries to synchronize many times, so every NsdManager
is still active, despite stopping service discovery.
以下是我的代码:
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)具有变化的上下文.
My current solution for this, is to make class containing NsdManager (NsdTest in above example) a singleton with changing context.
即使停止服务发现后,NSdManager线程仍在持续运行这一事实并没有改变,但是在恢复应用程序之后至少只有一个活动的NsdManager线程.
It doesn't change the fact that NSdManager thread is constantly running even after stopping service discovery, but at least there is only one active NsdManager thread after resuming application.
也许这不是最优雅的方式,但对我来说已经足够了.
Maybe it's not the most elegant way, but is enough for me.
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;
}
...}
如果有人知道更好的解决方案,请发布它.
If anybody knows better solution, please post it.
这篇关于NsdManager不会停止服务发现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!