I am making an android application as part of a school assignment.
I need to be able to display a timer in hh:mm:ssand update the timer every second.
I have managed to come up with the code i think will produce the results i need, but i cannot get the AsyncTask to execute every second. This is my current code:
TimerHand timerHand = new TimerHandling(timerTextView);
Timer timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                timerHand.execute();
            } },1000, 1000); // 1000ms == 1 second
This is the Async task this is a nested class inside the class which holds the above code, and the declaration of the TextView tv:
   class TimerHandling  extends AsyncTask<Void, Void, Void>{
        private long secs, mins, hours, millis;
        private String timeString;
        private TextView tv;
        private long startTime;
        private boolean stop;
        private Handler handler;
        public TimerHandling(TextView tv){
            this.tv = tv;
            startTime = System.currentTimeMillis();
            stop = false;
            handler = new Handler();
        }
        @Override
        protected Void doInBackground(Void... params) {
            while(stop != true){
                millis = System.currentTimeMillis() - startTime;
                hours += TimeUnit.MILLISECONDS.toHours(millis);
                mins +=  TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis));
                secs += TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MILLISECONDS.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis));     
                timeString = String.format("%02d:%02d:%02d",hours, mins, secs);
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        tv.setText(timeString);
                    }
                });
            }
            return null;
        }
        public void setStopCondition(boolean condition){
            this.stop = condition;
        }
    }
        }
It produces the following logCat output:
01-23 18:00:27.865: E/AndroidRuntime(14458): FATAL EXCEPTION: AsyncTask #5
01-23 18:00:27.865: E/AndroidRuntime(14458): Process: dcs.aber.ac.uk.cs211.group02, PID: 14458
01-23 18:00:27.865: E/AndroidRuntime(14458): java.lang.RuntimeException: An error occured while executing doInBackground()
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.os.AsyncTask$3.done(AsyncTask.java:300)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at java.util.concurrent.FutureTask.run(FutureTask.java:242)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at java.lang.Thread.run(Thread.java:841)
01-23 18:00:27.865: E/AndroidRuntime(14458): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:824)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.view.View.requestLayout(View.java:16431)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.view.View.requestLayout(View.java:16431)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.view.View.requestLayout(View.java:16431)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.view.View.requestLayout(View.java:16431)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:352)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.view.View.requestLayout(View.java:16431)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.widget.TextView.checkForRelayout(TextView.java:6600)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.widget.TextView.setText(TextView.java:3813)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.widget.TextView.setText(TextView.java:3671)
01-23 18:00:27.865: E/AndroidRuntime(14458):    at android.widget.TextView.setText(TextView.java:3646)
I understand that is is caused because the nested class has a different View so it cannot update the TextView, how can i overcome this?
When i run my code, i can see it executing and after about 2 seconds the app will crash wth the posted error message.
Update:
public void startCountingTimer() {
final Handler handler = new Handler();
final Runnable task = new Runnable() 
{ 
    @Override
    public void run() {
        millis = System.currentTimeMillis() - startTime;
        hours += TimeUnit.MILLISECONDS.toHours(millis);
        mins +=  TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis));
        secs += TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MILLISECONDS.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis));     
        timeString = String.format("%02d:%02d:%02d",hours, mins, secs);
        handler.postDelayed(task, 1000); //problem on this line
    }
};
task.run();   
}
I have pointed out the problem with a single line comment, "task" is undeclared.