Stephen
Stephen

Reputation: 762

Updating two consecutive textviews using threads

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

Answers (2)

JAL
JAL

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

Gligor
Gligor

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

Related Questions