Reputation: 762
I have been reading up about threads in my java book and I wanted to try making updates with two consecutive threads at the same time.
OF course though threads can't update the UI. I have used handlers a little bit but only by passing messengers from one class to another to capture location from a service to an activity.
But this must be simpler than that.
I assume I should use AsyncTask but i want to count 1-10 in each field and I don't want to keep dipping in and out of the asynctask class.
Any pointers appreciated
Stephen
UPDATE
So I did a little more experimenting. I wrote a handler method to handle any messages sent to it. It checks which field it should be updating and then performs a setText on said field. Here is the code
Handler myHandler = new Handler(){
public void handleMessage(Message msg){
msg = Message.obtain();
Bundle bundle = msg.getData();
String fieldName = bundle.getString("fieldName");
int count = bundle.getInt("count");
if(fieldName=="text1"){
text1.setText(count);
}else{
text2.setText(count);
}
}
};
I then have some code in the onCreate of my activity which launches two threads and each thread passes a messages with my int count to the handler. It also passes in a TextView name so my handler knows which textview it should be updating. Here is the code...
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text1 = (TextView)findViewById(R.id.text1);
text2 = (TextView)findViewById(R.id.text2);
new Thread(){
public void run(){
for(int i=1;i<10;i++){
message = Message.obtain(myHandler);
Bundle bundle = new Bundle();
bundle.putCharSequence("fieldName", "text1");
message.setData(bundle);
myHandler.sendMessageDelayed(message, 1000);
}
}
}.start();
new Thread(){
public void run(){
for(int i=1;i<10;i++){
message = Message.obtain(myHandler);
Bundle bundle = new Bundle();
bundle.putCharSequence("fieldName", "text2");
message.setData(bundle);
myHandler.sendMessageDelayed(message, 1000);
}
}
}.start();
}
But I am getting an error on the setText
05-17 17:13:00.013: ERROR/AndroidRuntime(966): android.content.res.Resources$NotFoundException: String resource ID #0x0
Any ideas?
Upvotes: 0
Views: 320
Reputation: 3319
If you really want to run two additional threads, that can be done with handlers. Simply create ONE handler for your activity and switch on what. Then launch two threads and when each thread completes send a message to the handler using the appropriate what value. Then update the appropriate text view in the handler as you are back in the UI thread in the handler:
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();
break;
case 1:
this.removeMessages(1);
Toast.makeText(Main.this,"Message1", Toast.LENGTH_SHORT).show();
break;
default:
super.handleMessage(msg);
break;
}
}
};
Simply replace the toast with your UI update code. You can launch a thread as in:
// DISPLAY ON CLICK HANDLER
threadButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Thread thread= new Thread( new Runnable() {
public void run() {
try { // DO NOT TOUCH THE UI HERE
Thread.sleep(1000); // mimic time consuming task
}
catch(Exception e){
}
myHandler.sendEmptyMessage(0);
}
});
thread.setDaemon(true);
thread.start();
}
});
If you just want to count from i= 1-10 seconds, you do not even need to use threads, just use postMessageDelayed by looping and calling:
myHandler.sendEmptyMessageDelayed(0, 1000); // what 0, 1 second
You can pass (preferably immutable) data in the messages as in:
Message msg= Message.obtainMessage(0);
Bundle b= new Bundle();
b.putString("stringData",outString);
msg.setData(b);
handler.sendMessage(msg);
and retrieve it as in:
Bundle b= msg.getData();
String data="";
if (b != null){
data= b.getString("stringData");
}
If you only need one additional thread, I would use asyncTask.
Upvotes: 1
Reputation: 2940
Here's what you can do. You are on the right track about using AsyncTask, so extend the class and put your counting in the progress update function. You should have something like this:
private class BackgroundTask extends AsyncTask<Void, Void, Void> {
int i;
protected void onPreExecute() {
i = 0;
}
@Override
protected Void doInBackground(Void... arg0) {
i++;
publishProgress(i);
}
protected void onProgressUpdate(Integer... progress) {
TextView tv1 = (TextView) Main.this.findViewById(R.id.textView1)
TextView tv2 = (TextView) Main.this.findViewById(R.id.textView2)
tv1.setText(i);
tv2.setText(i);
}
protected void onPostExecute(Void result) {
i = null;
}
}
where Main
is your activity and textView1
and textView2
are your text views that you are going to update.
Upvotes: 1