在Android中使用网络服务发现时出现了内部错误。

7
在使用开发者页面上的示例和教程进行NSDManager的第一次实现时,该应用程序成功启动了发现并找到了设备。 然而,现在似乎出现了问题... 当程序启动后,在一些初始化之后,代码进入以下方法并成功运行:
public void discoverServices() {
    Log.d(TAG, "Initializing discovery on NSD");
    mNsdManager.discoverServices(
            SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener);
} 

收到日志消息。大约5分钟后,程序会输出以下内容:
05-21 11:08:32.518: E/NsdCamera(12236): Discovery failed: Error code:0
05-21 11:08:32.518: W/dalvikvm(12236): threadid=12: thread exiting with uncaught exception (group=0x40c9c930)
05-21 11:08:32.518: E/AndroidRuntime(12236): FATAL EXCEPTION: NsdManager
05-21 11:08:32.518: E/AndroidRuntime(12236): java.lang.NullPointerException
05-21 11:08:32.518: E/AndroidRuntime(12236):    at android.net.nsd.NsdManager$ServiceHandler.handleMessage(NsdManager.java:338)
05-21 11:08:32.518: E/AndroidRuntime(12236):    at android.os.Handler.dispatchMessage(Handler.java:99)
05-21 11:08:32.518: E/AndroidRuntime(12236):    at android.os.Looper.loop(Looper.java:137)
05-21 11:08:32.518: E/AndroidRuntime(12236):    at android.os.HandlerThread.run(HandlerThread.java:60)

还有其他服务:

05-21 11:50:49.108: E/NativeDaemonConnector.ResponseQueue(8858): Timeout waiting for response
05-21 11:50:49.108: E/mDnsConnector(8858): timed-out waiting for response to 10 mdnssd discover 6 _http._tcp.
05-21 11:50:49.108: E/NsdService(8858): Failed to discoverServices com.android.server.NativeDaemonConnector$NativeDaemonFailureException: command '10 mdnssd discover 6 _http._tcp.' failed with 'null'

错误代码“0”在NSDManager类中被描述为内部错误。我所做的主要更新是在名为NsdCamera的助手类中访问上下文。以下是一些可能有问题的代码片段:
助手类构造函数:
public NsdCamera(CameraChooseActivity context) {
    mContext = context;
    updateUI =  new UpdateUI();
    mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
    mServiceName = new Vector<NsdServiceInfo>();

辅助类 NSD 初始化:

public void initializeNsd() {
    initializeDiscoveryListener();
}

public void initializeDiscoveryListener() {
    mDiscoveryListener = new NsdManager.DiscoveryListener() {

        @Override
        public void onDiscoveryStarted(String regType) {
            Log.d(TAG, "Service discovery started");
        }
        /**
         * A name check to see if the DNS discovery was correct. Checks if it contains 
         * AXIS and has the desired MAC address-space
         * @param hostname ,the inputted hostname from the discovery cycle
         * @return true if it's an Axis camera. 
         */
        public boolean nameCheck(String hostname){
            return (hostname.contains("AXIS") && hostname.contains("00408C"));

        }
        @Override
        public void onServiceFound(NsdServiceInfo service) {
            Log.d(TAG, "Service discovery success: " + service.getServiceName());
            if (!service.getServiceType().equals(SERVICE_TYPE)) {
                Log.d(TAG, "Unknown Service Type: " + service.getServiceType());
            } else if (nameCheck(service.getServiceName())){
                mServiceName.add(service);
//                  updateUI.execute(new BundleUI(mContext,service, null));
            }
        }

        @Override
        public void onServiceLost(NsdServiceInfo service) {
            Log.e(TAG, "service lost" + service);
            if(mServiceName.remove(service)){
                //TODO
                Log.e(TAG, "remove the view, service is lost");
            }
        }

        @Override
        public void onDiscoveryStopped(String serviceType) {
            Log.i(TAG, "Discovery stopped: " + serviceType);
            //Necessary??
            mServiceName.clear();
        }

        @Override
        public void onStartDiscoveryFailed(String serviceType, int errorCode) {
            Log.e(TAG, "Discovery failed: Error code:" + errorCode);
            mNsdManager.stopServiceDiscovery(this);
        }

        @Override
        public void onStopDiscoveryFailed(String serviceType, int errorCode) {
            Log.e(TAG, "Discovery failed: Error code:" + errorCode);
            mNsdManager.stopServiceDiscovery(this);
        }
    };
}

CameraChooseActivity -> onCreate正在调用帮助类

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_camerachoose);

    //Setup the animation for the text in the Relativelayout
    mDescription = (TextSwitcher) findViewById(R.id.camera_add);
    mDescription.setFactory(this);
    mDescription.setInAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_in));
    mDescription.setOutAnimation(AnimationUtils.loadAnimation(this, android.R.anim.fade_out));
    mDescription.setText(getText(R.string.camera_add));

    //Building alert dialog
    mBuilder = new AlertDialog.Builder(this,AlertDialog.THEME_HOLO_DARK);
    mBuilder.setMessage(R.string.dialog_about).setTitle(R.string.action_about);
    mBuilder.setIcon(android.R.drawable.ic_dialog_info);

    mLayout = (RelativeLayout) findViewById(R.id.layout_camerachoose);

    //Initialize the NSD
    mNSDHelper = new NsdCamera(this);
    mNSDHelper.initializeNsd();
2个回答

5
根据我的经验,我认为这是一个监听器生命周期的问题。
因为您向系统NSD服务提供了两个监听器,一个用于startServiceDiscovery(),另一个用于stopServiceDiscovery()。当系统访问这些监听器时,您需要确保这些监听器仍然存在。
一个事实是,onStartDiscoveryFailed()在调用startServiceDiscovery()后2分钟被调用,与监听器的生命周期相比,这应该是很长的时间。
因此,如果监听器是一个本地对象,并且在调用startServiceDiscovery()后被释放,它可能会导致NSD服务崩溃。
以下代码片段确保不要调用任何NsdManager api。
@Override
public void onStartDiscoveryFailed(String serviceType, int errorCode) {
     Log.i(TAG, "onStartDiscoveryFailed : Error code:" + errorCode);
}

@Override
public void onStopDiscoveryFailed(String serviceType, int errorCode) {
    Log.i(TAG, "onStopDiscoveryFailed : Error code:" + errorCode);
}

祝你好运。


好的回答!感谢您的帮助。 实际上它解决了空指针问题!但是“内部错误”(错误代码0)仍然存在:S - Mazze

3

重启DUT就解决了问题。不得不说这个错误相当奇怪。我认为守护进程崩溃了,没有重新启动。

(如果有人能够发布分析或提供更好的解决方案,请发布)


什么是DUT?我遇到了相同的错误,但我的设备会自动重启。 - fsschmitt
DUT是指测试设备。很多人遇到了这个问题,一些设备因为守护程序崩溃而重新启动,但是我的并没有…… - Mazze
不太确定这是否应该标记为正确答案。 - Vlad Ilie
有趣的是,我见过一些设备重新启动,而有些则只是挂起。 - slott

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接