我正在學習Android藍牙編程。我從Google的Android開發人員網站上覆制了大部分代碼以供學習。這個想法是監聽服務器上的連接是在一個新線程中完成的,而不會阻塞UI線程。當收到連接請求時,連接在另一個線程上完成,最後在另一個線程上完成通信。Android藍牙:從UI線程開始的線程阻塞UI線程
問題是,當我從UI線程啓動偵聽線程時,它會自動阻塞,並且沒有顯示UI(凍結)。下面是示例代碼:
public void onCreate(Bundle savedInstance) {
super.onCreate(savedInstance);
setContentView(R.layout.activity_main);
...
badapter = BluetoothAdapter.getDefaultAdapter();
if (badapter == null) {
Toast.makeText(this, "No bluetooth device.", Toast.LENGTH_SHORT).show();
return;
}
if (!badapter.isEnabled()) {
Toast.makeText(this, "Bluetooth is disabled.", Toast.LENGTH_SHORT).show();
return;
}
pairedDevices = new HashMap<String, String>();
discoveredDevices = new HashMap<String, String>();
showDevices();
registerBroadcastReceiver();
//this thread blocks UI thread
ListenThread listen = new ListenThread();
listen.run();
}
而且聽螺紋:
public class ListenThread extends Thread {
MainActivity main;
CommunicateThread communicateThread;
private final BluetoothServerSocket serverSocket;
public ListenThread() {
main = MainActivity.getInstance();
BluetoothServerSocket tmp = null;
try {
tmp = main.badapter.listenUsingRfcommWithServiceRecord(main.NAME, main.MYUUID);
} catch (final IOException e) {
main.handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(main, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
serverSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
//keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = serverSocket.accept();
} catch (final IOException e) {
main.handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(main, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
break;
}
// If a connection was accepted
if (socket != null) {
//call communication thread once connection is established
communicateThread = new CommunicateThread(socket);
communicateThread.run();
try {
serverSocket.close();
} catch (final IOException e) {
main.handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(main, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
break;
}
}
}
}
我認爲需要使用'listen.start();'來啓動Thread而不是調用run方法 –
我真是太傻了!這可能是原因嗎? – birraa
這是原因。這是否意味着當我調用run時,它是在UI線程中執行的呢? – birraa