Pausing with handler and postDelayed in android

John Octavious picture John Octavious · Aug 15, 2013 · Viewed 34.4k times · Source

I'm very new to android programming so please forgive my noobie-ness. I'm trying to create a very simple activity that will have one TextView in the middle of the Layout and just have it switch to a different text every couple of seconds. For example, the TextView will say "text1", pause for a couple of seconds, then say "text2, and pause again. Eventually, I want to add more texts and have them all cycle one after another. I know this seems like a super simple thing but I'm mainly trying to learn about threads and handlers at this moment. Anyways, I've read up on how we should keep lengthy things off the UI thread to prevent an error so I thought I'd use a handler to simply switch between 2 texts on screen. Unfortunately, I can't get this to work. Here's some code:

public class MainActivity extends Activity {

String[] myarray = {"text1" , "text2"};
int arraylength = myarray.length;
int count;
Handler handler = new Handler();

TextView mytexts;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mytexts = (TextView)findViewById(R.id.my_texts);
    mytexts.setText(myarray[0]);

    Thread t = new Thread( new Runnable(){
        public void run() {
            for (int count = 0; count < arraylength; count++){
                handler.postDelayed(new Runnable(){
                    public void run() {
                        mytexts.setText(myarray[1]);
                    }                   
                }, 7000);
            }
        }
    });
    t.start();
    }
}

From what I can see in the logcat, the handler seems to run postDelayed one right after another (in my code's case, it does NOT wait 7 seconds with the postDelay to do another postDelayed). Also, I would like to make the 1 in "mytexts.setText(myarray[1]);" be the same as "count" in the for loop so it can be the same as one of the strings in the array but that gives me an error. I've been stuck on this for hours and other examples I've found online seem way too complicated for someone like me who mainly wants to get the basics down before I can tackle other things. Any help at all with any of this would be much appreciated. Thank you.

Answer

JRomero picture JRomero · Aug 15, 2013

postDelayed is non blocking, meaning it would add it to a queue of I'll do this later. So what you are probably seeing is all text updates happening together at the 7th second. I say this because you are postDelaying from the onCreate method when in reality you probably want to do it from onResume or even onPostResume.

Also there is no reason to create a thread to add runnables to the post queue. Your code should look more like this: (Note the time to delay multiplier)

@Override
protected void onResume() {
    super.onResume();
    for (int count = 0; count < arraylength; count++){
        handler.postDelayed(new Runnable(){
            @Override
            public void run() {
                mytexts.setText(myarray[count]);
            }
        }, 7000 * (count + 1));
    }
}