我开发了一个与串口设备通信的蓝牙应用程序,到目前为止,通信(启动连接,数据交换和终止线程)工作正常。
然而,在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错误,是否有任何解决方法?
非常感谢提前。
答案 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代码的类似问题的建议解决方案