NsdManager不会停止服务发现

Daw*_*ski 17 android android-lifecycle android-nsd

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());
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

在主要Activity:

private NsdTest mNsdTest;

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

@Override
protected void onPause() {
    mNsdTest.stopListening();
    super.onPause();
}
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?

Daw*_*ski 7

我目前的解决方案是使包含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;
}
...}
Run Code Online (Sandbox Code Playgroud)

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