dorien
dorien

Reputation: 5387

How to setText from a separate Thread in Android

I want to setText from within a Thread.

This is my code of the Thread:

private class GenerateThread implements Runnable {
    public void run(){
            // generate the first music
            music = generate(prevmusic, prevmusic.length);
            prevmusic = music;

            // write the midi
            writeMidi(music, song);
            textOut.setText("Initialising...");
            });
    }
}

in my main code, I use

Thread t = new Thread(new GenerateThread());
    t.start();

It does not allow me to setText from within the thread. Following some posts on internet, I have tried using a handler, but that gave me errors, I think I am double defining Runnable this way.

Handler handler (before main)

private class GenerateThread implements Runnable {
    public void run(){
            handler.post(new Runnable() {
            // generate the first music
            music = generate(prevmusic, prevmusic.length);
            prevmusic = music;

            // write the midi
            writeMidi(music, song);
            textOut.setText("Initialising...");
            });
    }
}

How can I setText from within the Thread? Thanks!

Upvotes: 4

Views: 1628

Answers (2)

Frohnzie
Frohnzie

Reputation: 3569

One can only update the UI from the UI thread. runOnUiThread will allow you to run an action on the UI thread the next time it executes. You can do something like:

runOnUiThread(new Runnable() {
  public void run() {
      textOut.setText("Initialising...");
  }
});

EDIT:

private class GenerateThread implements Runnable {
   public void run(){
      // generate the first music
      music = generate(prevmusic, prevmusic.length);
      prevmusic = music;

      // write the midi
      writeMidi(music, song);

      // Update the UI
      MyActivity.this.runOnUiThread(new Runnable() {
        public void run() {
          textOut.setText("Initialising...");
        }
      });
   }
}

Upvotes: 3

zapl
zapl

Reputation: 63955

besides runOnUiThread there is also View#post(Runnable) which I would prefer here because you don't need ugly looking references to the outer Activity (MyActivity.this.runOnUiThread()).

private class GenerateRunnable implements Runnable {
    public void run() {
        // this code is executed in a background thread.
        // generate the first music
        music = generate(prevmusic, prevmusic.length);
        prevmusic = music;

        // write the midi
        writeMidi(music, song);
        textOut.post(new Runnable() {
            public void run() {
                // this code is executed on the UI thread.
                textOut.setText("Initialising...");
            }
        });
    }
}

@Override
protected void onResume() {
    super.onResume();
    new Thread(new GenerateRunnable()).start();
}

Also don't confuse Runnable and Thread. A Runnable is just an ordinary class with a run() method. It can be and often is executed on a new Thread. If you want you can also make GenerateThread a real Thread like so:

private class GenerateThread extends Thread {
    @Override
    public void run() {
        // code here.
    }
}
// start somewhere
new GenerateThread().start();

And besides using classic Thread you could also think about using AsyncTask since that is made exactly for tasks that do something long running and need to update the UI afterwards or when there is progress.

Upvotes: 4

Related Questions