开发者

Thread in Android causes phone crash

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 = 开发者_如何学C1;
        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


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.


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


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜