So here is how i would do this
create member variables of your activity:
private BackgroundWorkerThread m_bgThread = null;
protected Handler m_bgHandler = null;
See below my BackgroundWorkerThread class and then to initialize the thread and handler in your main activity in onCreate():
// Notice we pass the Handler Constructor this because we are implementing the interface
// in our activity
m_bgHandler = new Handler(this)
m_bgThread = new BackgroudnWorkerThread();
m_bgThread.start();
make sure you have your activity implements Handler.Callback
interface which will add this method to your Activity:
@Override public boolean handleMessage(Message msg)
{
switch(msg.what){
case 0:
// Will update the UI on the Main Thread
updateUI(msg.obj);
break;
case 1:
// rejoin the Thread with the main Thread
try {
m_bgThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
return true;
}
inside each case statement is where you do message passing to the background thread.
for example calling sendFirstMessage() somewhere in your activity:
public void sendFirstMessage(){
// Passes the 0 to the background Handler handleMessage
m_bgThread.workerHandler.obtainMessage(0).sendToTarget();
}
So then in your Activity's handler handleMessage() override
case 0:
updateUI(msg.obj);
break;
and then
public void updateUI(Object obj){
text.setText(obj.toString());
// Call to tell Background Thread to shut down looper
m_bgThread.workerHandler.obtainMessage(1).sendToTarget();
// Call to tell the Main Thread no more updates needed
m_bgHandler.obtainMessage(1).sendToTarget();
}
Then create your background thread class as a child class of your activity:
private class BackgroundWorkerThread extends Thread implements Handler.Callback{
private Looper workerLooper;
protected Handler workerHandler;
@Override public void run()
{
// Set up the Handler and Looper
Looper.prepare();
workerLooper = Looper.myLooper();
workerHandler = new Handler(workerLooper, this);
Looper.loop();
}
@Override public boolean handleMessage(Message msg)
{
switch(msg.what){
case 0:
// now this function is being called to run on the background Thread
beginListenForData();
break;
case 1:
workerLooper.quit();
break;
}
return true;
}
}
// This method is now being execute in the background
public void beginListenForData()
{
int bytesAvailable = 3;
while(!Thread.currentThread().isInterrupted())
{
try{
bytesAvailable = mmInStream.available();
if(bytesAvailable > 0)
{
byte[] packetBytes = new byte[bytesAvailable];
mmInStream.read(packetBytes);
bytesAvailable = mmInStream.available();
String s = new String(packetBytes);
// Instead of trying to set the text view here, send a message back to
// the Activity to update the UI on the Main thread
// text.setText(s);
// Passes 0, and the String Object to the Activity Handler
m_bgHandler.obtainMessage(0, s).sendToTarget();
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
This is a little difficult to wrap your head around but this is how its done, manually creating a thread, using a looper to check for messages in the background, and then passing messages to the activity from the background thread to Update the UI.
Good Luck! any questions feel free to ask.
Or you could take the easiest route possible ideology taken from http://android-developers.blogspot.com/2009/05/painless-threading.html
public void beginListenForData()
{
String s = null;
new Thread(new Runnable(){
public void run(){
int bytesAvailable = 3;
while(!Thread.currentThread().isInterrupted())
{
try{
bytesAvailable = mmInStream.available();
if(bytesAvailable > 0)
{
byte[] packetBytes = new byte[bytesAvailable];
mmInStream.read(packetBytes);
bytesAvailable = mmInStream.available();
s = new String(packetBytes);
// Takes Care of updating the UI
text.post(new Runnable(){
public void run(){
text.setText(s);
}
});
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}