Внутренняя ошибка при использовании обнаружения сетевых служб в Android

Во время первой реализации 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();

Инициализация вспомогательного класса 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)

Простой перезапуск DUT оказался решением проблемы. Надо сказать, что ошибка довольно странная. Я думаю, что демон разбился и неперезапустить.

(Если кто-то может опубликовать анализ или найти лучшее решение, пожалуйста, опубликуйте его)

 Vlad Ilie21 дек. 2014 г., 22:40
не совсем уверен, если это должно быть помечено как правильный ответ
 slott27 мар. 2016 г., 23:02
Интересно - яЯ видел, как несколько устройств перезагружаются, а некоторые просто зависают.
 Mazze28 июн. 2013 г., 11:08
DUT = тестируемое устройство. У многих есть проблема, некоторые устройства перезагружаются из-за сбоя демона, однако min не ...stackoverflow.com/questions/16907102/...
 fsschmitt27 июн. 2013 г., 20:18
Что такое DUT? У меня та же ошибка, но мое устройство перезагружается.
Решение Вопроса

Основываясь на моем опыте, я полагаю, что это проблема жизни слушателя.

Поскольку вы предоставляете два прослушивателя системной службе NSD, один для startServiceDiscovery (), а другой для stopServiceDiscovery (). Вы должны убедиться, что эти слушатели все еще живы, когда система обращается к этим слушателям.

Одним из фактов является то, что onStartDiscoveryFailed () вызывается через 2 минуты после вызова startServiceDiscovery (), это должно быть длительное время по сравнению со временем жизни слушателя.

Поэтому, если прослушиватель является локальным объектом и освобождается после вызова startServiceDiscovery (), это может вызвать сбой службы NSD.

public void stopServiceDiscovery (слушатель NsdManager.DiscoveryListener)

Остановите обнаружение службы, инициированное с помощью findServices (). Об обнаружении активной службы уведомляется приложению с помощью onDiscoveryStarted (String), и оно остается активным до тех пор, пока приложение не вызовет обнаружение остановки службы. Об успешной остановке уведомляется с помощью вызова onDiscoveryStopped (String).

При невозможности остановить обнаружение службы приложение уведомляется через onStopDiscoveryFailed (String, int).

Параметры listener Это должен быть объект listener, который был передан в DiscoverServices (String, int, NsdManager.DiscoveryListener). Он идентифицирует обнаружение, которое должно быть остановлено, и уведомляет об успешной остановке.

и ниже фрагмента убедитесь, что не вызывают ни один 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);
}

Удачи.

 Mazze03 мар. 2015 г., 16:22
Хороший ответ! Спасибо за помощь. Ну, это фактически решило нулевой указатель! Тем не менее "внутренняя ошибка" (код ошибки 0) все еще сохраняется: S

Ваш ответ на вопрос