Here is some sample code demonstrating how to launch multiple background threads in a determined order with a minimal of confusion. This can be done using a single handler and message passing concurrency. Note that all the calls to Thread.sleep are there to mimic a time intensive task. First declare the necessary imports;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;
Then in onCreate we will launch the first thread on a button click. This thread completes some work, sends a message with what(0) and then completes some more work. When it exits, it sends a second message with what(1) to signal completion.
// DISPLAY ON CLICK HANDLER
threadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//startActivity(intent);
Thread thread= new Thread( new Runnable() {
public void run() {
try {
Thread.sleep(1000);
}
catch(Exception e){
}
myHandler.sendEmptyMessage(0);
try {
Thread.sleep(3000);
}
catch(Exception e){
}
myHandler.sendEmptyMessage(1);
}
});
thread.setDaemon(true);
thread.start();
}
});
Finally, in the handler we will launch a second thread when the first thread fires off an empty message with a what of 0. When the second thread is done it sends a message with what(2). At this point there are two new threads running simultaneously in a determined manner. We can then trap the successful completion of both threads on what(1) and what(2).
private Handler myHandler= new Handler(){
@Override
public void handleMessage(Message msg){
switch(msg.what){
case 0:
this.removeMessages(0);
Toast.makeText(Main.this,"Message0", Toast.LENGTH_SHORT).show();
Thread thread= new Thread( new Runnable() {
public void run() {
try {
Thread.sleep(3000);
}
catch(Exception e){}
myHandler.sendEmptyMessage(2);
}
});
thread.setDaemon(true);
thread.start();
break;
case 1:
this.removeMessages(1);
Toast.makeText(Main.this,"Message1", Toast.LENGTH_SHORT).show();
break;
case 2:
this.removeMessages(2);
Toast.makeText(Main.this,"Message2", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
break;
}
}
};
Pretty simple! You can also pass data using messages as in:
Message msg= Message.obtainMessage(0);
Bundle b= new Bundle();
b.putString("stringData",outString);
msg.setData(b);
handler.sendMessage(msg);
You can then retrieve the data in the message what(0) handler as in:
Bundle b= msg.getData();
String data="";
if (b != null){
data= b.getString("stringData");
}
You can minimize concurrency conflicts by passing immutable objects to and from threads and avoiding the use of shared memory from within the threaded code.
JAL