10

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.

John Octavious
  • 221
  • 1
  • 3
  • 9
  • Why don't you remove the `postDelayed` and use a `post` with a `while` and then do some `Thread.sleep(time)`? – Rotary Heart Aug 15 '13 at 06:13
  • @RotaryHeart the postDelay method will post code to be executed on the main thread after the delay. You don't need to sleep the thread. In this particular case he doesn't need the Thread at all! – Ali Aug 15 '13 at 06:16
  • @Ali Yes you are right, I didn't want to change his code, but to tell him how to do it with that code. – Rotary Heart Aug 15 '13 at 06:20
  • I actually did try using the Thread.sleep approach at first but I've raed in many other places that handlers are the way to go for pauses in code. Is this true or is this just some kind of preference among programmers? – John Octavious Aug 15 '13 at 14:25

2 Answers2

19

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));
    }
}
JRomero
  • 4,878
  • 1
  • 27
  • 49
  • Yes, all text updates are happening at the 7th second. I'm a bit unclear on why I don't need to make a new thread, though. Does postDelayed do the 7-second wait in a background thread automatically? I know this wait would cause an error on the UI which is why I originally thought I needed a new thread. – John Octavious Aug 15 '13 at 14:33
  • You've got it, it would "wait" outside of the current (UI) thread. – JRomero Aug 15 '13 at 15:00
  • Your welcome. Marking question as answered helps return the favor ;) – JRomero Aug 15 '13 at 16:49
  • If I put 7000 instead of 7000*(count + 1) for second parameter of postDelayed function, my program will see all text updates happening together at the 7th second. Why? I really confused! :( – sandra Sep 11 '14 at 08:30
  • Like i stated postDelay is a timed, well... delay. without incrementing the time between when each letter all `Runnable`s fire at 7 secs instead ot 7 secs, 14 sec, 21 sec, etcs. – JRomero Sep 12 '14 at 03:43
2

This is because your loop is setting all your handlers to run after 7 seconds not 7 seconds after each other but but after 7 seconds from now. You can either add in the postDelayed method or use the postAtTime method in handler .

Also, you don't need to do this in a thread, you can get rid of that altogether.

Ali
  • 12,354
  • 9
  • 54
  • 83