2013-02-18 7 views
12

私はSDK 10(2.3.3)でコンパイルしています:受け入れる前にBluetoothサーバーソケットをキャンセルすると、プロセス全体が終了します。どうして?

android:minSdkVersion="10" 
android:targetSdkVersion="16" 

私は2台のソニーエリクソンのスマートフォンでテストしています。 OneにはAndroid 2.3.7と4.0.1があります。

私はlistenUsingInsecureRfcommWithServiceRecordを使用して、Bluetoothで新しいサーバーソケットを開き、接続を待ち受けます。

接続が正常に受け入れられれば、すべて正常に動作します。私もサーバーソケットをキャンセルしようとすることができますが、それはちょうど作成された接続ソケットを気にしていないようです。

しかし、bluetoothServerSocket.close();行が実行されるとすぐに接続を受け入れる前にサーバーソケットを取り消したい場合、アクティビティ全体が閉じられ、プロセスが終了します。さらに、これはで、私が扱うことができる通常の例外ではありません。

実際には、logcat自体も終了します!そして、私はすぐにあなたが下記を参照することができ、エラーをつかむために、再びそれを実行する必要があります。

Zygote D Process 25471 terminated by signal (11) 
    295   InputDispatcher W channel '2c2e20a8 com.pligor.test/activities.MainActivity (server)' ~ Consumer closed input channel or an error occurred. events=0x8 
    295   InputDispatcher E channel '2c2e20a8 com.pligor.test/activities.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed! 
    295    dalvikvm D GC_FOR_ALLOC freed 1299K, 21% free 13252K/16583K, paused 93ms 
    295   InputDispatcher W Attempted to unregister already unregistered input channel '2c2e20a8 com.pligor.test/activities.MainActivity (server)' 
    295  BluetoothService D Tracked app 25471 diedType:10 
    295  BluetoothService D Removing service record 10009 for pid 25471 
    132   SurfaceFlinger D Release buffer at 0x61c08 
    295   WindowManager I WINDOW DIED Window{2c2e20a8 com.pligor.test/activities.MainActivity paused=false} 
    295   ActivityManager I Process com.pligor.test (pid 25471) has died. 
    295   ActivityManager W Force removing ActivityRecord{2c021800 com.pligor.test/activities.MainActivity}: app died, no saved state 
    295   WindowManager W Failed looking up window 
    295   WindowManager W java.lang.IllegalArgumentException: Requested window [email protected] does not exist 
    295   WindowManager W at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7165) 
    295   WindowManager W at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:7156) 
    295   WindowManager W at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:1545) 
    295   WindowManager W at android.os.BinderProxy.sendDeathNotice(Binder.java:417) 
    295   WindowManager W at dalvik.system.NativeStart.run(Native Method) 
    295   WindowManager I WIN DEATH: null 
    295  BluetoothEventLoop D Property Changed: UUIDs : 11 
    295 hAdapterStateMachine D BluetoothOn process message: 51 
    295  InputManagerService W Got RemoteException sending setActive(false) notification to pid 25471 uid 10040 

注:信号(11)で終了したプロセスは、セグメンテーションフォールト(http://en.wikipedia.org/wiki/SIGSEGV)を意味します。

try { 
    isCancelled = true; 
    bluetoothServerSocket.close(); 
} catch { 
    case e: IOException => throw new NotClosedException; 
} 

private val bluetoothServerSocket: BluetoothServerSocket = try { 
    bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(MY_SERVICE_NAME_INSE‌​CURE, MY_UUID_INSECURE); 
} 
catch { 
    case e: IOException => throw new ServerSocketException; 
} 

は私がソケットのBluetoothを閉じるには、このコードを使用します。EDIT

は、私は次のコード(Scala)を使用してのBluetoothサーバソケットを作成します

+0

上記のように主な問題は解決され、その信号が(11)の終端は、彼らがアクセスすべきではないか、それが存在していないメモリをアクセスするプログラムによって引き起こされるようです。あなたのプログラムが過度のメモリを使用する理由はわかりませんが、どれくらい使っているのかチェックしたいかもしれません。コードの投稿は、ここでトラブルシューティングを行う際に役立ちます。 – hBrent

+0

私は問題がないことを確認します。しかし、コードのどの部分を正確に追加したいのですか? –

+0

'bluetoothServerSocket.close();を呼び出すと、接続が確立されていないときに例外がスローされますか? – Houf

答えて

0

私はこの問題の回避策を見つけたと思います。これはまだ多くのデバイスでテストされていないためです。タイムアウト

を持って

次のコードはScalaのは、私がオーバーロードされたメソッドを利用(int)を受け入れるの回避策について

あるだから我々は、無限ループの状態のための変数を持っています私達はちょうどwhileループで

を受け入れる繰り返し

private var toContinue = true; 

の下にあなたが見ています今では
while (toContinue) { 
    try { 
    //this is a blocking call and will only return on a successful connection or an exception, or on timeout 
    val socket = bluetoothServerSocket.accept(10000); //msec 

    connectionAccepted(socket); 
    } catch { 
    case e: IOException => { 
     Logger("accepting timed out"); 
    } 
    } 
} 

代わりに、我々はちょうど偽

def cancel() { 
    toContinue = false; 
} 

実際のコードに変数を設定しているbluetoothServerSocket.close()を呼び出すあなたはwhileループの終了時に何かをするコールバック関数を必要とするので、もう少し複雑ですしかし、私は少し研究を行ってきた

2

I fソケットを閉じると、ユーザが接続されているときにtrueに設定され、ユーザが切断したときにfalseに設定されるブールフラグを作成しないと、それほど大きなダメージを与えません。ユーザーが以前に接続されたときに閉じることができます。

+0

あなたの回避策は問題ありませんが、テストしても問題はありませんか? –

+0

いいえあなたが記述しているのと同じ問題がないと私はそれをテストしていませんが、以前に開いていた場合のみソケットを閉じるだけです。同意する? – Jeremy

+0

ソケットは確かに開かれていますが、まだ接続されていません(まだ受け入れられていません)。また、リスニングのBluetoothサーバーソケットを開いたままにしておくと、インターネットの他の読み取り値から正しく覚えていれば、もう1つの理由は、リッスンソケットが無限ではないということです。だから、新しいソケットを開く〜20回で十分です例外 –

6

私は同様の問題を経験しましたが、問題の根本的な原因はソケットで複数回閉じることでした。この問題を解決するために、closeメソッドが複数回呼び出されないようにするために、特別クラスにBluetoothソケットをラップしました。

ブルートゥースソケットで作成されたストリームを閉じると、ソケットでcloseを呼び出すことができることに注意してください。以下はこの問題を解決します。

public class CloseOnceBluetoothSocket 
{ 
private final BluetoothSocket mSocket; 
private boolean mIsClosed; 

public CloseOnceBluetoothSocket(BluetoothSocket socket) 
{ 
    this.mSocket = socket; 
} 

public void connect() throws IOException 
{ 
    mSocket.connect(); 
} 

public InputStream getInputStream() throws IOException 
{ 
    return new FilterInputStream(mSocket.getInputStream()) { 
     @Override 
     public void close() throws IOException 
     { 
      CloseOnceBluetoothSocket.this.close(); 
     } 
    }; 
} 

public OutputStream getOutputStream() throws IOException 
{ 
    return new FilterOutputStream(mSocket.getOutputStream()) { 
     @Override 
     public void close() throws IOException 
     { 
      CloseOnceBluetoothSocket.this.close(); 
     } 
    }; 
} 

public void close() throws IOException 
{ 
    synchronized (mSocket) { 
     if (!mIsClosed) { 
      mSocket.close(); 
      mIsClosed = true; 
     } 
    } 
} 
} 
+0

ジャスティンありがとう。あなたのクラスは他の状況で役に立つかもしれないので、私はクラスを維持します。私はCloseOnceBluetoothSocketで自分のコードのすべての部分を置き換えましたが、残念ながらこれは違いはありませんでした。 Bluetoothソケットを閉じる際に問題はありませんが、問題はBluetooth **サーバー**ソケットを閉じることです。信号(11).' によって終了プロセス9414 'しかし、私はあなたのような回避策を見つけるか、そのAPI 10はあまりにも私の状況のた​​めにバグがあると、おそらく新しいAPIは、この問題を解決しているだろうかを決定する必要があり推測:私はまだこれを取得しています。とにかくありがとう! ! –

+0

サーバーソケット用に同様のソリューションを実装しましたか? –

+0

はい!私はすでにjustとifステートメントを使っていました。しかし、2回の停止を実行する問題はありません。最初の呼び出しですべてがクラッシュします.. !! –

関連する問題