2013-05-21 5 views
7

Во время первой реализации NSDManager с использованием примеров и tutorial on the developer page приложение успешно запустило обнаружение и обнаружило устройства.Внутренняя ошибка с использованием Обнаружения сетевой службы в Android

Однако теперь, кажется, сломана ...

Когда программа запущена, после некоторой инициализации, код входит следующий метод и успешно работают:

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 class, как внутренняя ошибка. Основными обновлениями, которые я сделал, был доступ к контексту в вспомогательном классе под названием NsdCamera. Вот некоторые, вероятно, дурные код-фрагменты:

Helper-конструктор класса:

public NsdCamera(CameraChooseActivity context) { 
    mContext = context; 
    updateUI = new UpdateUI(); 
    mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE); 
    mServiceName = new Vector<NsdServiceInfo>(); 

Helper-класс НРД инициализации:

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(); 

ответ

3

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

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

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

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

общественного недействительный stopServiceDiscovery (NsdManager.DiscoveryListener слушатель)

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

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

Параметры прослушивателя Это должен быть объект-слушатель, который был отправлен , чтобы обнаружить службы (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); 
} 

Удачи.

+0

Хороший ответ! Спасибо за помощь. Ну, это на самом деле решило нулевой указатель! Однако «внутренняя ошибка» (код ошибки 0) по-прежнему сохраняется: S – Mazze

3

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

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

+0

Что такое DUT? У меня такая же ошибка, но мое устройство перезагружается. – fsschmitt

+0

DUT = тестирование устройства. Многие проблемы, некоторые устройства перезагрузки из-за сбоя демона, однако мин не ... http://stackoverflow.com/questions/16907102/android-network-printers-discovery-nullpointerexception – Mazze

+0

не совсем уверен, если это должно быть отмечено как правильный ответ –