Reputation: 502
I'm new to programming on android and I'm writing a simple application of a turn-based game that uses bluetooth. My app consists of Main Activity is responsible for starting a bluetooth connection and exchanging some configuration messages and a SecondActivity that implements a custom view with the game map. I can correctly pair the devices and exchange information between the two even in the custom view, the problem is that in the custom view I would wait to receive information without blocking the ui thread, at the moment I am waiting to receive data in this way
Custom view
state = bluetoothService.getState();
while(state != NOT_EMPTY){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
state = bluetoothService.getState();
}
info = bluetoothService.getMessage();
this obviously causes black screens and non-responsiveness, is there another way to wait to receive data?
The connection is managed through a BluetoothService class, with threads, the one that takes care of reading the data does this
private class ConnectedThread extends Thread {
private final BluetoothSocket mSocket;
private final InputStream mInStream;
private final OutputStream mOutStream;
public ConnectedThread(BluetoothSocket socket) {
mSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = mSocket.getInputStream();
tmpOut = mSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mInStream = tmpIn;
mOutStream = tmpOut;
}
public void run(){
byte[] buffer = new byte[1024];
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
// Read from the InputStream
try {
bytes = mInStream.read(buffer);
if(bytes != 0) {
String incomingMessage = new String(buffer, 0, bytes);
message = incomingMessage;
mState = NOT_EMPTY;
}
} catch (IOException e) {
break;
}
}
}
}
//getMessage method just returns message if not null
Upvotes: 0
Views: 1793
Reputation: 78945
The main idea is not to pull from the activity, but instead call a method of the activity from the background thread.
So when constructring your reader thread, pass a reference to the activity and create a handler:
private SecondActivity mActivity;
private Handler mActivityHandler;
public ConnectedThread(BluetoothSocket socket, SecondActivity activity) {
mActivity = activity;
mActivityHandler = new Handler(activity.getMainLooper());
...
}
When a message is received, call a method of the activity. The call must be done on the main thread, so use the handler:
final String message = incomingMessage;
Runnable runnable = new Runnable() {
@Override
public void run() {
mActivity.onMessageReceived(message);
}
};
mActivityHandler.post(myRunnable);
In the activity, do something with message:
public void onMessageReceived(String message) {
// handle the message...
}
Upvotes: 2