1

I have been trying to create a custom stopwatch that counts up in android. It needs to be fairly accurate down to 0.1s and with custom layout and images for the digits example: DIGITS.

It also needs to be able to run in the background after the app has been minimized or closed. To be more specific, to force the app to stay open while the timer is on (I don't know how to achieve this).

So far I have tried using Handlers, Runnables, scheduledExecutorService and the android Chronometer class.

Handlers had issues with performance, chewing up 45%> cpu usage (I think this was because of the UI continuously updating?). I have managed to have it working using the scheduledExecutorService with modest performance, but it still has issue with continuing in the background or during orientation changes.

I am trying to create something similar to the default clock stopwatch on the HTC one M7. It works in the background and during orientation changes without losing any time.

The timer will be in its own Fragment in an Activity using a ViewPager and sliding tab layout.

This is the runnable for the stopwatch

public Runnable run() {

    return new Runnable() {
        @Override
        public void run() {

            centiseconds++;
            if (centiseconds > 9) {
                centiseconds = 0;
                seconds++;
            }
            if (seconds > 59) {
                seconds = 0;
                minutes++;
            }
            if (minutes > 59) {
                minutes = 0;
                hours++;
            }

            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    updateCustomUI();

                }
            });
        }
    };
}

In the fragment i then initialize the scheduledExecutorService

ScheduledFuture scheduledFuture;
ScheduledExecutorService scheduledExecutorService;

To start timer

scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(run(), 0, 100, TimeUnit.MILLISECONDS);

and to Stop it

scheduledFuture.cancel(true);
nebuchadnezzar I
  • 125
  • 1
  • 12
  • You code will fail when the display is switched off or your app runs in background because Android then stops it and your counting code stops, too. Use CountDownTimer instead of your own second-counting code. – Robert Nov 18 '16 at 07:46
  • That would only be useful for counting down right? How would i implement it for counting UP? (as in a stopwatch). – nebuchadnezzar I Nov 18 '16 at 07:55
  • Read the documentation then you will see that there is an `onTick()` method which can be fired ever 1000 milliseconds. – Robert Nov 18 '16 at 08:02

2 Answers2

0

In this case you can Use IntentService with ResultReciver

GreenROBO
  • 4,725
  • 4
  • 23
  • 43
  • yes, as i've said in my question i have already tried using handlers. I found that their timings were not consistent enough for the timer i wanted to create. It also wouldn't solve the issue of being able to run in the background while the application is paused or stopped. Or am i missing something? – nebuchadnezzar I Nov 18 '16 at 07:07
  • I've Edited My Answer – GreenROBO Nov 18 '16 at 07:43
  • I'm still yet to go over intents and broadcast/Result receivers. I will learn it and give it a go. I will see where it gets me. – nebuchadnezzar I Nov 18 '16 at 07:51
  • It will never get you. You've to go and get it. What's Stopping you? For me, I've never got it while Studying, I learned it by myself. You can do the same. – GreenROBO Nov 18 '16 at 08:47
0

I have tried using the Android AnimationDrawable classes but the performance was about the same and androidDevelopers didn't have alot of documentation on it like the accuracy and potential to override etc.

So I decided my implementation was the most efficient, maxing out at about 10% and average 7% on my HTC one M7.

Though I am not sure if i correctly implemented the Animation class when i tried it, if someone knows exactly how it works then feel free to let me know.

Starting the scheduledExecutorService using different initialization seemed to have solved the background work.

Previously i initiated it using

scheduledExecutorService= Executors.newSingleThreadScheduledExecutor();

now i use

scheduledExecutorService= Executors.newScheduledThreadPool(16);

Any other arbitrary number for the threadpool seems to work just fine, I've yet to optimize it and find the right number of threads to use, but this helps the scheduledExecutorService to run in the background by having more threads it can pull from should some get destroyed when the activity or fragment gets destroyed.

nebuchadnezzar I
  • 125
  • 1
  • 12