tuna
tuna

Reputation: 105

Thread blocking UI in android

I am using this sample code from the Android Bluetooth guide, found here http://developer.android.com/guide/topics/connectivity/bluetooth.html under "Connecting as a Client".

private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;

public ConnectThread(BluetoothDevice device) {
    // Use a temporary object that is later assigned to mmSocket,
    // because mmSocket is final
    BluetoothSocket tmp = null;
    mmDevice = device;

    // Get a BluetoothSocket to connect with the given BluetoothDevice
    try {
        // MY_UUID is the app's UUID string, also used by the server code
        tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
    } catch (IOException e) { }
    mmSocket = tmp;
}

public void run() {
    // Cancel discovery because it will slow down the connection
    mBluetoothAdapter.cancelDiscovery();

    try {
        // Connect the device through the socket. This will block
        // until it succeeds or throws an exception
        mmSocket.connect();
    } catch (IOException connectException) {
        // Unable to connect; close the socket and get out
        try {
            mmSocket.close();
        } catch (IOException closeException) { }
        return;
    }

    // Do work to manage the connection (in a separate thread)
    manageConnectedSocket(mmSocket);
}

/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
    try {
        mmSocket.close();
    } catch (IOException e) { }
}

}

In my onCreate, I call

protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);
    super.onCreate(savedInstanceState);
    connectionManager= new ConnectionManager(this);
    connectionManager.start();

The connectionManager launches a ConnectThread and the connect thread successfully connects to another bluetooth device. However, the layout isn't rendered until the ConnectThread returns (exactly, when mmSocket.connect() stops blocking). How can I get the layout to display first?

Upvotes: 2

Views: 6658

Answers (3)

Luke Taylor
Luke Taylor

Reputation: 9599

Remember, setContentView() only takes action once the onCreate() method returns. Taking this into account, you should run the code in another thread and not in the UI thread.

Your code should look something like this:

protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_main);
    super.onCreate(savedInstanceState);
    new Thread(new Runnable() {

            @Override
            public void run() {
               connectionManager= new ConnectionManager(this);
               connectionManager.start();
            }
    }).start();
}

Upvotes: 0

Phuong Nguyen
Phuong Nguyen

Reputation: 909

You can wrap it in an async task http://developer.android.com/reference/android/os/AsyncTask.html

Upvotes: 0

Martin Cazares
Martin Cazares

Reputation: 13705

In stead of creating the connection manager from the UI Thread, why dont you create it in a worker thread as follows:

protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
new Thread(new Runnable() {

            @Override
            public void run() {
               connectionManager= new ConnectionManager(YourActivity.this);
               connectionManager.start();
            }
        }).start();

This way you never get to block the UI Thread, hope this helps...

Regards!

Upvotes: 1

Related Questions