Android中的线程导致手机崩溃

发布于 2024-11-27 05:21:33 字数 4565 浏览 0 评论 0原文

我不知道这段代码中出现了什么问题,因为我无法读取崩溃日志。我们不是在谈论应用程序崩溃,而是可能由死锁线程或某种锁定引起的电话崩溃。欢迎提出建议!


背景:

当我启动连接时,会显示一个对话框,当我按“后退”按钮时,对话框会冻结,一段时间后手机就会崩溃...

代码:

这是处理与设备的连接的线程。我在连接到设备时完全没有问题。我所知道的是,当我按下后退按钮时, 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

从来不烧饼 2024-12-04 05:21:33

好的,您正在从看似 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 call Thread.interrupt(). I'm not sure if a BluetoothSocket is interruptible, but let's hope. Then after interrupting, call close(), which probably shouldn't be called on the main thread.

九歌凝 2024-12-04 05:21:33

尝试在 keyCode_BACK 上使用 dialog.setOnKeyListener() 取消线程。试试这个会起作用的。

try to use dialog.setOnKeyListener() in that on keyCode_BACK cancel the thread. try this will work.

小红帽 2024-12-04 05:21:33

看起来您正在调用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文