Android中的线程导致手机崩溃
我不知道这段代码中出现了什么问题,因为我无法读取崩溃日志。我们不是在谈论应用程序崩溃,而是可能由死锁线程或某种锁定引起的电话崩溃。欢迎提出建议!
背景:
当我启动连接时,会显示一个对话框,当我按“后退”按钮时,对话框会冻结,一段时间后手机就会崩溃...
代码:
这是处理与设备的连接的线程。我在连接到设备时完全没有问题。我所知道的是,当我按下后退按钮时, mmSocket.connect()
正在运行。认为问题出在某个地方...
class ConnectThread extends Thread {
/**
*
*/
private Handler threadhandler;
private BluetoothDevice mmDevice;
private volatile BluetoothSocket mmSocket;
private Message toMain;
// private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public ConnectThread(Handler threadhandler, BluetoothDevice device) {
this.threadhandler = threadhandler;
this.mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
Method m = mmDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
mmSocket = (BluetoothSocket) m.invoke(mmDevice, 1);
}catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public void run() {
Looper.prepare();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
toMain = threadhandler.obtainMessage();
toMain.arg1 = 1;
threadhandler.sendMessage(toMain);
} catch (SecurityException e) {
Log.e("SecurityExcep", "Oh noes" , e);
toMain = threadhandler.obtainMessage();
toMain.arg1 = 2;
threadhandler.sendMessage(toMain);
Log.w("MESSAGE", e.getMessage());
}catch (IOException e) {
//Bad connection, let's get the hell outta here
try {
Log.e("IOExcep", "Oh noes" , e);
Log.w("MESSAGE", e.getMessage());
mmSocket.close();
toMain = threadhandler.obtainMessage();
toMain.arg1 = 2;
toMain.obj = e.getMessage();
threadhandler.sendMessage(toMain);
return;
} catch (IOException e1) {
Log.e("IOExcep2", "Oh noes" , e);
}
}
try {
mmSocket.close();
} catch (IOException e) {
Log.d("CONNECT_CONSTRUCTOR", "Unable to close the socket", e);
}
toMain = threadhandler.obtainMessage();
toMain.arg1 = 3;
threadhandler.sendMessage(toMain);
Looper.loop();
return;
// Now it should be paired.. only thing to do now is let the user commit to the rest
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
下一个代码是来自对话框创建者的代码片段,该线程称为 d
:
(...)
case DIALOG_BT_ADDING:
search_dialog = new ProgressDialog(this);
search_dialog.setTitle(R.string.adding);
search_dialog.setMessage(res.getText(R.string.bluetooth_add_accept));
search_dialog.setIndeterminate(true);
search_dialog.setCancelable(true);
search_dialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
Log.i("THREAD CONNECT", "Is it alive?: " + d.isAlive());
if(d != null && d.isAlive()){
d.cancel();
//d = null;
}
if(d2 != null && d2.isAlive()){
d2.cancel(false);
//d2 = null;
}
search_dialog.dismiss();
showDialog(DIALOG_NEW_DEVICE_FOUND);
}
});
return search_dialog;
(...)
这是执行 ConnectThread
的代码片段 -类
private void connectBluetooth(boolean nextstage, IOException e1){
if(!nextstage){
showDialog(DIALOG_BT_ADDING);
d = new ConnectThread(threadhandler, selected_car.getDevice());
d.start();
}
else{
if(e1 != null){
d2 = new BluetoothCheckThread(checkthreadhandler,mBluetoothAdapter,
5000, car_bt, after_bt);
d2.start();
search_dialog.dismiss();
}
else{
showDialog(DIALOG_BT_ADDING_FAILED);
}
}
}
希望你们能帮助我!感谢您的反馈
I have no idea what fails in this code because I have trouble reading the crash logs. We are not talking about a app-crash but a phone crash probably caused by either a deadlocked thread or a lock-up of some kind. Suggestions are welcomed!
Background:
When I initiate my connection a dialog shows and when I press the Back button the dialog freezes and after awhile the phone crashes...
Code:
This is the thread that handles the connection with the device. I have no issues connecting to a device at all. What I know is that mmSocket.connect()
running when I press the back button. Think the problem lies there somewhere...
class ConnectThread extends Thread {
/**
*
*/
private Handler threadhandler;
private BluetoothDevice mmDevice;
private volatile BluetoothSocket mmSocket;
private Message toMain;
// private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public ConnectThread(Handler threadhandler, BluetoothDevice device) {
this.threadhandler = threadhandler;
this.mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
Method m = mmDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
mmSocket = (BluetoothSocket) m.invoke(mmDevice, 1);
}catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
public void run() {
Looper.prepare();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
toMain = threadhandler.obtainMessage();
toMain.arg1 = 1;
threadhandler.sendMessage(toMain);
} catch (SecurityException e) {
Log.e("SecurityExcep", "Oh noes" , e);
toMain = threadhandler.obtainMessage();
toMain.arg1 = 2;
threadhandler.sendMessage(toMain);
Log.w("MESSAGE", e.getMessage());
}catch (IOException e) {
//Bad connection, let's get the hell outta here
try {
Log.e("IOExcep", "Oh noes" , e);
Log.w("MESSAGE", e.getMessage());
mmSocket.close();
toMain = threadhandler.obtainMessage();
toMain.arg1 = 2;
toMain.obj = e.getMessage();
threadhandler.sendMessage(toMain);
return;
} catch (IOException e1) {
Log.e("IOExcep2", "Oh noes" , e);
}
}
try {
mmSocket.close();
} catch (IOException e) {
Log.d("CONNECT_CONSTRUCTOR", "Unable to close the socket", e);
}
toMain = threadhandler.obtainMessage();
toMain.arg1 = 3;
threadhandler.sendMessage(toMain);
Looper.loop();
return;
// Now it should be paired.. only thing to do now is let the user commit to the rest
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
Next code is a snippet from the dialog creator, the thread is called d
:
(...)
case DIALOG_BT_ADDING:
search_dialog = new ProgressDialog(this);
search_dialog.setTitle(R.string.adding);
search_dialog.setMessage(res.getText(R.string.bluetooth_add_accept));
search_dialog.setIndeterminate(true);
search_dialog.setCancelable(true);
search_dialog.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
Log.i("THREAD CONNECT", "Is it alive?: " + d.isAlive());
if(d != null && d.isAlive()){
d.cancel();
//d = null;
}
if(d2 != null && d2.isAlive()){
d2.cancel(false);
//d2 = null;
}
search_dialog.dismiss();
showDialog(DIALOG_NEW_DEVICE_FOUND);
}
});
return search_dialog;
(...)
Here is a snippet of the code executing the ConnectThread
-class
private void connectBluetooth(boolean nextstage, IOException e1){
if(!nextstage){
showDialog(DIALOG_BT_ADDING);
d = new ConnectThread(threadhandler, selected_car.getDevice());
d.start();
}
else{
if(e1 != null){
d2 = new BluetoothCheckThread(checkthreadhandler,mBluetoothAdapter,
5000, car_bt, after_bt);
d2.start();
search_dialog.dismiss();
}
else{
showDialog(DIALOG_BT_ADDING_FAILED);
}
}
}
Hope you guys can help me!, thanks for any feedback
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
好的,您正在从看似 UI 线程的地方调用
BluetoothSocket.close()
。这可能导致“冻结”。当您说手机“崩溃”时,您的意思是它会重新启动吗?如果是这样,这是完全重启(屏幕返回到第一次打开手机时发生的情况)还是运行时重启(手机通常会显示某种动画,在 Nexus 设备上,是四色粒子喷雾)?如果不是重新启动,您的意思是您只会看到一个对话框,允许您终止该应用程序吗?
在任何一种情况下,您可能都希望获取对调用
BluetoothSocket.connect()
的线程的引用并调用Thread.interrupt()
。我不确定蓝牙套接字是否可中断,但让我们希望吧。然后在中断后,调用close()
,这可能不应该在主线程上调用。Okay, you're calling
BluetoothSocket.close()
from what looks like the UI thread. This is probably causing the "freeze".When you say the phone "crashes" do you mean it reboots? If so is this a full reboot (screen goes back to what happens when you first turn the phone on) or a runtime restart (phone typically shows some sort of animation, on Nexus devices, its the four-color particle spray)? If its not a reboot, do you mean you just get a dialog allowing you to kill the app?
In either case you may want to get a reference to the Thread that is calling
BluetoothSocket.connect()
and callThread.interrupt()
. I'm not sure if a BluetoothSocket is interruptible, but let's hope. Then after interrupting, callclose()
, which probably shouldn't be called on the main thread.尝试在 keyCode_BACK 上使用
dialog.setOnKeyListener()
取消线程。试试这个会起作用的。try to use
dialog.setOnKeyListener()
in that on keyCode_BACK cancel the thread. try this will work.看起来您正在调用 BluetoothSocket 上的 connect 和 close ,这是“不”。这似乎导致了僵局。有关详细信息,请参阅此链接。
It looks like you're calling connect and close on BluetoothSocket which is a "no no". It seems to cause a deadlock. See this link for more info.