4

我的应用程序在 Android 2.3.3 到 4.1.2 下运行良好,但由于 Android 4.2.2 和 Android 4.3,我有一个

fatal signal 11 (SIGSEGV) at 0x00....

当我关闭蓝牙插座时。

我搜索了很多论坛,主要的反应是

BluetoothSocket.close();

同时从两个不同的线程调用,但在我的代码中并非如此。

我在 A4.1.2 下使用三星 Galaxy Note 2(工作正常),在 A4.2.2 和 4.3 下使用 Nexus 4。

提前感谢您的建议!

编辑 1:这是操作蓝牙套接字的 2 个线程。

首先 :

    /**
 * This thread runs while attempting to make an outgoing connection with a
 * device. It runs straight through; the connection either succeeds or
 * fails.
 */
private class ConnectThread extends Thread {        
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;
    //private final UUID MY_UUID = java.util.UUID.randomUUID();

    public ConnectThread(BluetoothDevice device) {
        if(D) Log.d(TAG, "/S4B/ start connectThread ");
        mmDevice = device;
        BluetoothSocket connection = null;


        // Get a BluetoothSocket for a connection with the given BluetoothDevice
        try {
            if(D) Log.i(TAG,"/S4B/ Create RF Socket");
            Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
            connection = (BluetoothSocket) m.invoke(device, 1);
            //connection = device.createRfcommSocketToServiceRecord(MY_UUID);
            Utils.pause(100);
        } catch (Exception e) {
            Log.e(TAG, "/S4B/ create() failed", e);
        }
        mmSocket = connection;
        if(D) Log.i(TAG,"/S4B/ Socket initialized");
    }

    public void run() {
        if(D) Log.i(TAG, "/S4B/ BEGIN mConnectThread");
        setName("ConnectThread");

        if (mmSocket != null) {
            // Always cancel discovery because it will slow down a connection
            if(mAdapter.isDiscovering()){   
                mAdapter.cancelDiscovery();
            }

            // Make a connection to the BluetoothSocket
            try {
                // This is a blocking call and will only return on a successful connection or an exception
                if(D) Log.i(TAG,"/S4B/ Start socket connection");
                mmSocket.connect();
                if(D) Log.i(TAG,"/S4B/ End of socket connection");
            } catch (Exception e) {
                Log.e(TAG, "/S4B/ socket connect failed", e);

                // Close the socket
                try {
                    mmSocket.close();
                    if(D) Log.i(TAG,"/S4B/ close socket");

                } catch (IOException e2) {
                    Log.e(TAG,"/S4B/ unable to close() socket during connection failure",e2);
                }
                //Turn off the bluetooth - the Bluetooth STATE_OFF Broadcast will be received in welcome.class
                connectionFailed();
                return;
            }

            // Reset the ConnectThread because we're done
            synchronized (BluetoothConnectionService.this) {
                mConnectThread = null;
            }

            // Start the connected thread
            connected(mmSocket, mmDevice);
        } else {
            BluetoothConnectionService.this.start();
            connectionFailed();
        }
    }

    public void cancel() {
        try {
            if (mmSocket != null) {
                mmSocket.close();
            }
        } catch (IOException e) {
            Log.e(TAG, "/S4B/ close() of connect socket failed", e);
        }
    }
}

第二个:

    /**
 * This thread runs during a connection with a remote device. It handles all
 * incoming and outgoing transmissions.
 */
private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final DataInputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket) {
        Log.d(TAG, "/S4B/ Create ConnectedThread");
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // Get the BluetoothSocket input and output streams
        try {
            if(D) Log.i(TAG,"/S4B/ Get input and output stream");
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
            isConnected = true;
        } catch (IOException e) {
            Log.e(TAG, "/S4B/ Temp sockets not created", e);
            isConnected = false;
        }

        mmInStream = new DataInputStream(tmpIn);
        mmOutStream = tmpOut;
    }

    public void run() {
        setName("ConnectedThread");
        Log.i(TAG, "/S4B/ BEGIN mConnectedThread");

        while (isConnected) {
            Utils.pause(50);
            isConnected = checkConnection();
        }

    }

    /**
     * Check if the connection is still alive
     * 
     * @return true or false
     */
    private boolean checkConnection() {
        synchronized (mmInStream) {
            try {
                int len = mmInStream.available();
                if (len > 0) {// Checks the available amount
                    byte b[] = new byte[len];
                    if(D) Log.i(TAG,"/S4B/ start mmInStream readFully");
                    mmInStream.readFully(b, 0, len);
                    mHandler.obtainMessage(MESSAGE_READ, len, -1, b).sendToTarget();
                }

                return true;

            } catch (IOException ioe) {
                Log.e(TAG, "/S4B/ check connection, disconnected", ioe);
                connectionLost();
                return false; // Connection is lost.
            }
        }
    }

    /**
     * Write to the connected OutStream.
     * 
     * @param buffer
     *            The bytes to write
     */
    public void write(byte[] buffer) {
        try {
            mmOutStream.write(buffer);
        } catch (IOException e) {
            Log.e(TAG, "/S4B/ Exception during write", e);
            connectionLost();
            return;
        }
        // Share the sent message back to the UI Activity
        mHandler.obtainMessage(MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
    }

    public void cancel() {
        try {
            mmSocket.close();
            Utils.pause(1000);
        } catch (IOException e) {

            Log.e(TAG, "/S4B/ close() of connect socket failed", e);
        }
    }
}

编辑 2:我尝试仅使用一个线程来确保无法并行访问

BluetoothSocket

但结果完全一样。我一打电话

BluetoothSocket.close();

我收到致命信号 11 并且应用程序崩溃。

4

3 回答 3

7

我也遇到了这个问题。然而,对我来说close()不是原因。问题是在close(). 具体来说,在available()套接字关闭后对套接字输入流的调用导致了段错误。

于 2013-11-20T00:55:59.437 回答
5

我有同样的问题。在关闭套接字调用之前它对我有帮助

mConnectedThread.interrupt()

从外部类到 ConnectedThread run() 方法添加

public void run() {
    ...
    while (condition) {
        if (isInterrupted())
            return;
        ...
    }
    ...
}

确保线程不会从套接字的流中读取任何内容。之后你可以调用 mmSocket.close()

于 2014-02-11T06:37:10.523 回答
4

4.4.2我在Galaxy Grand 2设备中遇到了与 Android 相同的问题

我在@markrileybot answer给出的答案的帮助下解决了这个问题

在我的代码完成调用后,我正在访问该socket.available()方法。close()

要向@markrileybot 答案添加更多内容:

在调用之前我还添加了条件socket.close()

public void cancel() {
    try {
        if(mmSocket.isConnected())    // this is condition
        mmSocket.close();
        Utils.pause(1000);
    } catch (IOException e) {

        Log.e(TAG, "/S4B/ close() of connect socket failed", e);
    }
}

1如果您在 之间共享同一个套接字multiple threads,则应添加此条件,这将阻止close()在套接字已关闭时调用(not connected

2在调用socket.available()or之前socket.write(),我们应该检查socket.isConnected(),如果它返回,true那么只有我们应该进一步处理

于 2015-04-09T04:46:45.940 回答