然而现在它似乎被打破了……
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级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,"Discovery Failed: Error code:" + errorCode); mNsdManager.stopServiceDiscovery(this); } }; }
CameraChooseActivity – > onCreate正在调用helper-class
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();
解决方法
因为您为系统NSD服务提供了两个侦听器,一个用于startServiceDiscovery(),另一个用于stopServiceDiscovery().当系统访问这些侦听器时,您需要确保这些侦听器仍处于活动状态.
一个事实是,在调用startServiceDiscovery()2分钟后调用onStartDiscoveryFailed(),与侦听器的生命周期相比,它应该是一个很长的时间.
因此,如果侦听器是本地对象并在调用startServiceDiscovery()之后释放,则可能导致NSD服务崩溃.
public void stopServiceDiscovery (NsdManager.DiscoveryListener
listener)Stop service discovery initiated with discoverServices(). An active
service discovery is notified to the application with
onDiscoveryStarted(String) and it stays active until the application
invokes a stop service discovery. A successful stop is notified to
with a call to onDiscoveryStopped(String).Upon failure to stop service discovery,application is notified
through onStopDiscoveryFailed(String,int).Parameters listener This should be the listener object that was passed
to discoverServices(String,int,NsdManager.DiscoveryListener). It
identifies the discovery that should be stopped and notifies of a
successful stop.
并在下面的代码段确保不要调用任何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); }
祝好运.