I am writing an Android app that connects to a Bluetooth device, reads data sent from the device, adds it to an AChartEngine graph, and displays the data in a TextView.
My Bluetooth code is quite similar to the threaded implementation in the BluetoothChat sample code (it comes with the SDK). I can see in LogCat that the ConnectedThread
loop is executing and thus getting new data, but my TextView stops updating after 7 lines and the graph pauses intermittently (not to mention that it only responds to interaction intermittently). There aren't any errors being shown in LogCat. Also, if I remove the graph, the problem with the TextView persists.
Why is my UI thread not working when updated from my other threads?
Below are the relevant parts of my code. Each string sent over Bluetooth is received in ConnectedThread
and sent to BluetoothController.addToGraph()
, which then runs the NewPoints
AsyncTask
from the viewer
class.
private class ConnectedThread extends Thread {
public ConnectedThread(BluetoothSocket socket, String socketType) { ... } // Initialize input and output streams here
public void run() {
while (true) {
Log.i(TAG, "READ mConnectedThread");
// Read from the InputStream
byte[] buffer = new byte[1024];
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(BluetoothController.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
Log.i(TAG, "LOOPEND mConnectedThread");
}
}
}
public class BluetoothController extends Activity {
private viewer plotter;
public static final int MESSAGE_READ = 2;
// The Handler that gets information back from the BluetoothClass
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
addToGraph(readMessage);
break;
}
}
};
protected void addToGraph(String result) {
// process the string, create doubles x and y that correspond to a point (x,y)
plotter.new NewPoints().execute(x, y);
}
}
public class viewer extends Activity {
// initialize graph, etc.
@Override
protected void onResume() {
// Create handlers for textview
textHandler = new Handler();
// Set scrolling for textview
myTextView.setMovementMethod(new ScrollingMovementMethod());
protected class NewPoints extends AsyncTask<Double, Void, Void> {
@Override
protected Void doInBackground(Double... values) {
mCurrentSeries.add(values[0], values[1]); // x, y
if (mChartView != null) {
mChartView.repaint();
}
final Double[] messages = values;
textHandler.post(new Runnable() {
@Override
public void run() {
myTextView.append("(" + messages[0].toString() + ", " + messages[1].toString() + ") \n");
}
});
return null;
}
}
}
What gives? If more code is necessary, let me know.