问题
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?
回答1:
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!
回答2:
You can wrap it in an async task http://developer.android.com/reference/android/os/AsyncTask.html
回答3:
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();
}
来源:https://stackoverflow.com/questions/17845388/thread-blocking-ui-in-android