2012-12-07 8 views
7

Ich habe ein Problem mit Bluetooth in meiner App. Es scheint, dass nach 28 BluetoothSocket/BluetoothServerSockets alle Ports erstellt wurden. Die Sockets müssen nicht gleichzeitig geöffnet werden, es sind nur 28 Sockets, seit Bluetooth aktiviert wurde.Android: Bluetooth konnte keine Portnummer erhalten

Dies kann mit der BluetoothChat-Probe reproduziert werden, die in der Android Samples enthalten ist. Öffnen und schließen Sie die App einfach 15-mal (die App erstellt jedes Mal 2 Sockets). Am 15. Mal wird es zum Absturz bringen und wird auch weiterhin zum Absturz bringen, bis Sie deaktivieren und dann Bluetooth wieder aktivieren:

12-06 18:43:58.177: E/BluetoothSocket(18530): bindListen, fail to get port number, exception: java.io.IOException: read failed, socket might closed, read ret: -1 
12-06 18:43:58.193: E/BluetoothChatService(18530): Socket Type: Insecurelisten() failed 
12-06 18:43:58.193: E/BluetoothChatService(18530): java.io.IOException: Error: -1 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.bluetooth.BluetoothAdapter.createNewRfcommSocketAndRecord(BluetoothAdapter.java:1035) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.bluetooth.BluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(BluetoothAdapter.java:982) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at com.example.android.BluetoothChat.BluetoothChatService$AcceptThread.<init>(BluetoothChatService.java:280) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at com.example.android.BluetoothChat.BluetoothChatService.start(BluetoothChatService.java:119) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at com.example.android.BluetoothChat.BluetoothChat.onResume(BluetoothChat.java:131) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1185) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.Activity.performResume(Activity.java:5182) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2732) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2771) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2235) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread.access$600(ActivityThread.java:141) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.os.Handler.dispatchMessage(Handler.java:99) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.os.Looper.loop(Looper.java:137) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at android.app.ActivityThread.main(ActivityThread.java:5039) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at java.lang.reflect.Method.invokeNative(Native Method) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at java.lang.reflect.Method.invoke(Method.java:511) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
12-06 18:43:58.193: E/BluetoothChatService(18530): at dalvik.system.NativeStart.main(Native Method) 

Gibt es eine Möglichkeit, die Ports nach der Socket geschlossen ist zu befreien?

Antwort

6

Ich kann dieses Verhalten auf dem Gerät, das ich hier habe, überprüfen; obwohl die Anzahl der Male, die zum Absturz auf die gleiche Weise erforderlich ist, je nach Gerät variiert (ich denke, dass 20-25 Mal auf dem Galaxy Nexus mit 4.2 ausgeführt wurden), so scheint die verfügbare Anzahl von Port-Handles zu variieren. Ich kann auch die Information beitragen, dass das Problem kein Speicherleck in der Beispiel-App (oder Ihrer App für diese Angelegenheit) ist, da alle Instanzen von BluetoothSocket von Dalvik freigegeben und geschlossen wurden. Die hier aufgeführten Schritte testen nur das Problem auf BluetoothServerSocket, so dass unklar ist, ob das Problem speziell damit verbunden ist, obwohl es unwahrscheinlich scheint.

Zumindest auf meinen Geräten können Sie die App nicht einmal neu starten, bis der Status des Bluetooth-Adapters umgeschaltet wird. Das Problem liegt also definitiv in der zugrunde liegenden Verwaltung der Verbindungen auf dem Stack.

Ich würde einen Fehler mit Schritten hier reproduzieren http://b.android.com und ich würde gerne upvote werden.

+1

Danke für einen Blick! Ich habe hier einen Fehler gemeldet: [# 41110] (http://code.google.com/p/android/issues/detail?id=41110). Es dauerte 15 Mal, um die App sowohl auf meinem Galaxy Nexus als auch auf meinem Nexus 7 mit 4.2.1 zu stürzen. Mein Nexus One ist nie abgestürzt, hoffentlich ist es nur ein JB-Problem. – mattprecious

0

In letzter Zeit musste ich eine Lösung dafür finden. Upgrade von Android war keine Option.

Es stellt sich heraus, dass, anstatt mAcceptThread jedes Mal zu zerstören und neu zu erstellen, wenn eine Verbindung hergestellt oder unterbrochen wird, die ursprüngliche Instanz beibehalten und wiederverwendet wird. Dies minimiert die Auswirkung des Fehlers auf Ihre App.

Von der BluetoothChatService Datei, in der angeschlossenen() Funktion, kündige nicht mAcceptThread:

public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) { 
... 
... 
... 
// Cancel the accept thread because we only want to connect to one device 
//(Rather stay listening so comment out the cancel line!!) 
//If necessary, use some other state to prevent a second connection. 
//DONT CANCEL: if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;} 
... 
... 

In der AcceptThread Klasse, ändern Sie die Schleife in der run() Funktion:

  // Listen to the server socket if we're not connected 
//OLD LOOP:   while (mState != STATE_CONNECTED) 
//(Rather use STATE_NONE so the loop will only stop when the service does) 
      while (mState != STATE_NONE) 

Es kann andere Dinge in Ihrem Code zu tun geben, um die Idee richtig zu implementieren.jedes Mal, wenn der Service-Neustarts

BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(MainActivity.mac); 
        // Attempt to connect to the device 
        mChatService.connect(device, true); 

zu lösen das Problem „schlägt fehl, wenn wieder Anschluss für mehr als 28-mal“ i kommentiert:

0

i in einem Zeit Handler in dem Fragmente verwenden, um wieder zu verbinden selbst wenn verlieren Verbindung:

//BluetoothChatService.this.start(); 

auch alles, was ich die Teile kommentiert, wo der Sockel schließt:

//socket.close(); 

//mmServerSocket.close(); 

//mmSocket.close(); 

//mSecureAcceptThread.cancel(); 

und hat eine nicht null Erkennung für den Thread akzeptieren und verbunden Thead nicht zum Scheitern verurteilt:

if(mAdapter != null) { 
         tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, 
           MY_UUID_SECURE); 
        }else{ 
         mAdapter = BluetoothAdapter.getDefaultAdapter(); 
         //mState = STATE_NONE; 
        } 

und

if(mmServerSocket != null) { 
         socket = mmServerSocket.accept(); 
        } 

Noch bekomme ich zufällige Verbindung unterbrochen wird, aber der Service neu verbindet und alles funktioniert.

Verwandte Themen