android中的线程阻塞UI

时间:2013-07-24 21:47:58

标签: android multithreading bluetooth

我正在使用Android蓝牙指南中的示例代码,该指南位于“作为客户端连接”下的http://developer.android.com/guide/topics/connectivity/bluetooth.html

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) { }
}

}

在我的onCreate中,我致电

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

connectionManager启动ConnectThread,连接线程成功连接到另一个蓝牙设备。但是,在ConnectThread返回之前不会呈现布局(确切地说,当mmSocket.connect()停止阻塞时)。 如何让布局首先显示?

3 个答案:

答案 0 :(得分:1)

除了从UI线程创建连接管理器之外,为什么不在工作线程中创建它,如下所示:

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();

这样你永远不会阻止UI线程,希望这有助于...

问候!

答案 1 :(得分:0)

答案 2 :(得分:0)

请记住,setContentView()仅在onCreate()方法返回后才执行操作。考虑到这一点,您应该在另一个线程中而不是在UI线程中运行代码。

您的代码应如下所示:

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();
}