BluetoothChat应用程序在Android 4.4中的onDestroy()崩溃

时间:2014-01-27 09:23:18

标签: android multithreading bluetooth android-4.4-kitkat

我开发了一个与串口设备通信的蓝牙应用程序,到目前为止,通信(启动连接,数据交换和终止线程)工作正常。

然而,在Nexus 4(Android 4.4.2)上测试时,我遇到了蓝牙连接的奇怪问题。当我使用后退按钮退出应用程序时,onDestroy()按正常方式触发,但应用程序崩溃并显示错误消息“不幸的是,已停止。”

我检查了日志,没有崩溃点。显示以下错误

  

“01-29 16:57:11.372:A / libc(8684):致命信号11(SIGSEGV)at   0x00000008(代码= 1),线程8775(线程327)“

`,然后是非常长的调试堆栈跟踪。

我尝试使用Android开发者网站上的示例蓝牙应用来测试它是否是我自己的实施问题,并且发生同样的崩溃问题。

<!---- code -->
@Override
public void onDestroy() {
super.onDestroy();
// Stop the Bluetooth chat services
if (mChatService != null) mChatService.stop();
if(D) Log.e(TAG, "--- ON DESTROY ---");
}

在BluetoothChatService.java中,这是stop()的代码。

/**
 * Stop all threads
 */
public synchronized void stop() {
    if (D) Log.d(TAG, "stop");

    if (mConnectThread != null) {
        mConnectThread.cancel();
        mConnectThread = null;
    }

    if (mConnectedThread != null) {
        mConnectedThread.cancel();
        mConnectedThread = null;
    }

    if (mSecureAcceptThread != null) {
        mSecureAcceptThread.cancel();
        mSecureAcceptThread = null;
    }

    if (mInsecureAcceptThread != null) {
        mInsecureAcceptThread.cancel();
        mInsecureAcceptThread = null;
    }
    setState(STATE_NONE);
}

Android 4.2.1(Galaxy Nexus)和Android 4.3(Samsung S4)不会出现这种情况。

知道怎么解决这个问题吗?如果是Android错误,是否有任何解决方法?

非常感谢提前。

4 个答案:

答案 0 :(得分:3)

试试这个: 在mConnectedThread类中,创建一个像

的标志
private boolean stopThread = false;

然后在run()方法中更改循环:

while (true) {...

while (!stopThread) {...

然后将其添加到cancel()方法中:

stopThread = true;
try {
    mmSocket.close();
} catch ...

这应该解决你的问题,不知道为什么他们首先使用无限循环,因为取消方法将在必须被调用时被调用...

希望这会有所帮助:)。

答案 1 :(得分:1)

问题是您的应用尝试在close()之后访问套接字。具体来说,套接字关闭后对套接字available()的{​​{1}}的调用会导致段错误。它帮助我确保线程不会从套接字的流中读取任何内容。之后,您可以致电inputstream。基本上,在关闭它之前中断你的线程并让你的线程听取中断。

将您的mmSocket.close()方法更改为以下内容:

stop()

并在您的public synchronized void stop() { if (D) Log.d(TAG, "stop"); /* if (mConnectedThread.mmSocket.isConnected()){ mConnectedThread.interrupt(); mConnectThread.cancel(); }*/ if (mConnectThread != null) { mConnectThread.cancel(); mConnectThread = null; } if (mConnectedThread != null) { mConnectedThread.interrupt(); mConnectedThread.cancel(); mConnectedThread = null; } if (mSecureAcceptThread != null) { mSecureAcceptThread.cancel(); mSecureAcceptThread = null; } setState(STATE_NONE); } 方法中添加以下代码段:

ConnectedThread run()

希望这有帮助! :)

答案 2 :(得分:0)

此崩溃的来源是

处的空指针异常
private final void setStatus(int resId) {
    final ActionBar actionBar = getActionBar();
    actionBar.setSubtitle(resId);
}

但只有在提供onDestroy()回调时才会发生这种情况。 (顺便说一下,这个回调是由于后退按钮,即onPause(),然后是onStop(),然后是onDestroy()。

我找到了两种方法来处理这种情况。 1)在BluetoothChat.java中替换代码

private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MESSAGE_STATE_CHANGE:
            if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
            switch (msg.arg1) {
            case BluetoothChatService.STATE_CONNECTED:
                setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));
                mConversationArrayAdapter.clear();
                break;
            case BluetoothChatService.STATE_CONNECTING:
                setStatus(R.string.title_connecting);
                break;
            case BluetoothChatService.STATE_LISTEN:
            case BluetoothChatService.STATE_NONE:
                setStatus(R.string.title_not_connected);
                break;
            }
            break;

通过

private final Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case MESSAGE_STATE_CHANGE:
            if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
            switch (msg.arg1) {
            case BluetoothChatService.STATE_CONNECTED:
                setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));
                mConversationArrayAdapter.clear();
                break;
            case BluetoothChatService.STATE_CONNECTING:
                setStatus(R.string.title_connecting);
                break;
            case BluetoothChatService.STATE_LISTEN:
                setStatus(R.string.title_not_connected);
                break;
            case BluetoothChatService.STATE_NONE:
                //setStatus(R.string.title_not_connected);
                break;
            }
            break;

2)另一种方法是转移代码

// Stop the Bluetooth chat services
if (mChatService != null) mChatService.stop();

从onDestroy()到onPause()回调函数。

我在Android 4.2.2上运行我的应用程序因此不确定上述解决方案是否适用于android 4.4。

<强>加 在更改屏幕方向后,应用程序也会崩溃。为了解决这个问题,我通过Android Manifest文件为我的应用程序采用了纵向方向。但是使用onSaveInstanceState(bundle)可以实现更好的解决方案。

答案 3 :(得分:0)

另请参阅BluetoothChat example: NullPointerException上有关BlueToothChat代码的类似问题的建议解决方案