1

I am trying to create textview in android which display the remaining time(seconds).

Have used runOnUiThread and Hadnler for this and everything seems working fine(sysout and debug shows that both threads are executed and value is updated properly). However, on UI the textview value is not updated properly. It gets updated with last value when the thread completes.

I am writing the below code inside private method of the fragment.

final TextView timerText = (TextView) mainView.findViewById(R.id.timerText); timerText.setText(R.string.maxAllowedSeconds);

    handler.post(new Runnable() {
        @Override
        public void run() {
            while(true)
            {
                System.out.println("Text:"+ ""+maxAllowedSeconds);
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                maxAllowedSeconds--;
                if(maxAllowedSeconds <= 0)
                    break;
                getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("Running on UI Thread : " + maxAllowedSeconds);
                        timerText.setText("" + maxAllowedSeconds);
                    }
                });
            }
        }
    });

Gone through many of the previous questions in this area but none seems to have concrete solutions for this problem.

Thanks in advance.

SOLUTOIN:

Finally I used AsynchTask which worked perfectly as expected.

private class RapidFireAsyncTimerTask extends AsyncTask<Integer, Integer, Void> {

        private Context context;
        private View rootView;

        public RapidFireAsyncTimerTask(Context ctx, View rootView) {

            this.context = ctx;
            this.rootView = rootView;
        }

        @Override
        protected Void doInBackground(Integer... params) {

            int maxSec= params[0];
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                publishProgress(--maxSec);
                if (maxSec <= 0)
                    break;
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(final Integer... values) {

            ((TextView) rootView.findViewById(R.id.timerText)).setText("" + values[0]);
        }

        @Override
        protected void onPostExecute(Void aVoid) {

            //next task
        }
    }
Chota Bheem
  • 1,106
  • 1
  • 13
  • 31

1 Answers1

0

Instead of Handler, it worked with AsynchTask(No runOnUiThread needed).

 public RapidFireAsyncTimerTask(Context ctx, View rootView) {

        this.context = ctx;
        this.rootView = rootView;
    }

    @Override
    protected Void doInBackground(Integer... params) {

        int maxSec= params[0];
        while (true) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            publishProgress(--maxSec);
            if (maxSec <= 0)
                break;
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(final Integer... values) {

        ((TextView) rootView.findViewById(R.id.timerText)).setText("" + values[0]);
    }

    @Override
    protected void onPostExecute(Void aVoid) {

        //next task
    }
}
Chota Bheem
  • 1,106
  • 1
  • 13
  • 31