6

Basically, I am trying to run a seconds counter and a levels counter. For every 10 seconds I want to ++level.
But that's not implemented as yet, so far I am just trying to get the seconds to display but I am getting runtime exceptions and a crash.
Googling I see that its because I am trying to update the UI from my thread and thats not allowed. So I guess I am going to need asyncTask, but I have no idea how to do that with my simple little program. Please help or give me some alternatives...

package com.ryan1;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class main extends Activity {

int level = 1;
int seconds_running=0;

TextView the_seconds;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    the_seconds = (TextView) findViewById(R.id.textview_seconds);



    Thread thread1 = new Thread(){
        public void run(){
            try {
                sleep(1000); Log.d("RYAN", " RYAN ");

                updated_secs();
            } catch (Exception e) {
                e.printStackTrace();
                Log.d("RYAN", " "+e);
            }
        }
    };
    thread1.start();
}

public void updated_secs(){
    seconds_running++;
    the_seconds.setText(" "+seconds_running);
}
}
Ryan
  • 9,821
  • 22
  • 66
  • 101

3 Answers3

6

Create a Handler in your UI thread, then in the worker thread send a message to the handler (Handler.sendMessage(...)).

The message will be processed on your UI thread, so you can update the text widget correctly. Like this:

private Handler myUIHandler = new Handler()
{
    @Override
    public void handleMessage(Message msg)
    {
        if (msg.what == some_id_you_created)
        {
            //Update UI here...
        }
    }
};

Then in your thread, to send a message to the handler you do this:

Message theMessage = myHandler.obtainMessage(some_id_you_created);
myUIHandler.sendMessage(theMessage);//Sends the message to the UI handler.
Ryan Reeves
  • 10,209
  • 3
  • 42
  • 26
  • Hey! We share the same name :) Can you give me some sample code please? After hours on this I am feeling pretty brain dead... – Ryan Mar 20 '11 at 22:57
3

For this kind of thing, it is a waste to use another thread; it is just a waste and makes it so you have to dael with multithreading issues. Instead, just use Handler.sendDelayedMessage():

static final int MSG_DO_IT = 1;
static final long TIME_BETWEEN_MESSAGES = 10 * 1000;  // 10 seconds

Handler mHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_DO_IT: {

                // Update your UI here...

                Message newMsg = obtainMessage(MSG_DO_IT);
                sendMessageDelayed(newMsg, TIME_BETWEEN_MESSAGES);
            } break;
        }
    }
}

@Override
void onResume() {
    super.onResume();

    // Start the timer, executing first event immediately.
    Message newMsg = mHandler.obtainMessage(MSG_DO_IT);
    mHandler.sendMessage(newMsg);
}

@Override
void onPause() {
    super.onPause();

    // Stop the timer.
    mHandler.removeMessages(MSG_DO_IT);
}

Note that this implementation will have some drift -- the actual time between messages is TIME_BETWEEN_MESSAGES + (time to dispatch message). If you need something that won't drift, you can do the timing yourself by using Hander.sendMessageAtTime() and incrementing the new time with a constant value each time, starting with an initial time you get with SystemClock.uptimeMillis() in onResume().

hackbod
  • 90,665
  • 16
  • 140
  • 154
1

There is a great example of a Timer built using AsyncTask and a Handler with the postDelayed method.

You are correct that updating the UI from a background is a no-no.

Robby Pond
  • 73,164
  • 16
  • 126
  • 119
  • Thanks for replying! I actually saw that, but I want to do this via threads because I want to learn threads as I heard its quite important as you go along in the lessons and finally come to making some sort of a game... Can you help me do this via threads please? – Ryan Mar 20 '11 at 22:22
  • I also don't see AsyncTask task being used here – Seth Hikari Aug 16 '11 at 20:10