【问题标题】:Listener already in use (Service Discovery)侦听器已在使用中(服务发现)
【发布时间】:2014-09-12 19:08:22
【问题描述】:

我无法解决一项服务,而另一项服务正在解决?如果这就是错误的含义......等待解决的方法是什么?

@Override
public void onServiceFound(NsdServiceInfo service) {
    Log.d(TAG, "Service found. " + service);
    if (service.getServiceType().equals(SERVICE_TYPE)) {
        if (service.getServiceName().contains(mServiceName)) {
            mNsdManager.resolveService(service, mResolveListener);
        }
    }
}

java.lang.IllegalArgumentException:监听器已在使用 android.net.nsd.NsdManager.resolveService(NsdManager.java:613) 在 com.example.miguel.broadcast.LocalService$2.onServiceFound(LocalService.java:145)

【问题讨论】:

  • 也许您的问题与此报告的错误有关? code.google.com/p/android/issues/detail?id=56830
  • @Okas 我使用的是 Android L,但从未收到此错误。
  • 找到解决方案了吗?我的棒棒糖设备上也出现此错误,但其他设备上没有。
  • @tastypython 有点...我做了一个解决方法。使用其中一种条件时总是会触发错误(我希望我能在这里提供更多帮助),尝试删除或更改一个条件,它最终会起作用。我前段时间删除了我的项目,对不起!阅读 Google 提供的示例代码,很有帮助。
  • 感谢您的回复,即使是来自 google 的示例应用程序也已损坏,因此我已切换到 jmdns。我想 Google 的 nsd API 开发得不好。

标签: java android service-discovery


【解决方案1】:

您不必等待! 如果您查看 javadocs resolveService(NsdServiceInfo serviceInfo, NsdManager.ResolveListener 监听器) here 您会注意到,对于参数侦听器,它说“在成功或失败时接收回调。不能为空。不能用于活动服务解析。”

因此,为了使其正常工作,只需执行以下操作:

mNsdManager.resolveService(service, new MyResolveListener());

MyResolveListener 在哪里:

private class MyResolveListener implements NsdManager.ResolveListener {
        @Override
        public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
            //your code
        }

        @Override
        public void onServiceResolved(NsdServiceInfo serviceInfo) {
            //your code
        }
    }

希望这会有所帮助:)

【讨论】:

  • 您好,谢谢您的回答。我什至不记得我是如何解决这个问题的,但现在它对互联网很有用! ;)
【解决方案2】:

我也遇到了这个问题,并且一直在关注 NsdChat here 中列出的 Android NsdHelper 实现。此示例显示在 NsdHelper 类中创建单个 NsdManager.ResolveListener mResolveListener,并将该 ResolveListener 用于对 NsdManager.resolveService 的所有调用。

从here 我读到“一个单独的监听器将用于每个活动的注册或发现请求”。

所以不要使用类变量 mResolveListener,而是在每次调用 mNsdManager.resolveService 时创建一个新的侦听器:

@Override
public void onServiceFound(NsdServiceInfo serviceInfo) {
    Log.d(TAG, "Service found: "+ serviceInfo);
    if (serviceInfo.getServiceType().equals(SERVICE_TYPE)){
        mNsdManager.resolveService(serviceInfo, new NsdManager.ResolveListener() {
            @Override
            public void onResolveFailed(NsdServiceInfo serviceInfo, int errorCode) {
                Log.e(TAG, "Resolve Failed: " + serviceInfo);
            }
            @Override
            public void onServiceResolved(NsdServiceInfo serviceInfo) {
                Log.i(TAG, "Service Resolved: " + serviceInfo);
            }
        });
    }
}

【讨论】:

    【解决方案3】:

    您需要确保您没有传入已注册的侦听器对象。您可以看到导致此行为更改的提交here。

    这是提交消息文本:

    记录并执行“每个侦听器一个请求”规则

    NsdManager 的 API 和实现意味着一个单独的 侦听器将用于每个活动的注册或发现 要求。这没有正式记录或正确执行,并且 如果应用程序使用 一次监听多个请求。

    更新文档以明确要求。

    在提交新请求时强制执行限制 加工;如果 Listener 已被用于跟踪活动 请求,抛出异常。

    记录应用应注销服务并取消的事实 应用程序停止时的服务发现(在 KitKat 和之前 如果不这样做,它们会泄漏。)

    重新排序“释放侦听器”操作以在侦听器之前发生 回调,这样监听器就可以被应用程序重用一次 回调已输入 - 这消除了竞争条件。 记录下来。

    通过 2:错别字,添加有关 API 级别的文档,更改为使用 为“忙碌的侦听器”明确定义的返回值。

    另外,如果您从 Android 开发者网站(即NsdChat.zip 或类似的内容)下载 NsdChat 示例项目,则只是一个警告,该项目代码可能已过期。

    尝试使用 master 分支上的最新代码...您可以将其从 here 复制并粘贴到您的示例项目中。

    【讨论】:

      猜你喜欢
      • 2010-10-28
      • 2019-01-23
      • 2021-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多