The thing is, that I have to keep a thread running for a pretty long time (it's really an indefinite time, could be 1 minute or even months), and it needs to update the UI about once every 1 milisecond...
There is the Executor, AsyncTask, Handler and the native Thread class... but which one is better for this case?
The problem with AsyncTask is that it is destroyed (or detached from the Activity?) like one hour or so after the Activity starts running on background, and the user could return to the Activity at any time just to find that it's not working (and even causing memory leaks), and the UI lags when changing to another activity or even pulling down the notification panel.
Natural Threads are even more laggy due to the post() method being called on the TextView every time I need an update to the UI (remember that I need to report progress about once every 1 milisecond)...
tl:dr
I'm developing a long running stopwatch, that can measure from miliseconds to days, weeks or even years. What is the best UI-intensive threading technique for this?
Could you please help me? Thanks!!
--- Edit:
Solved. It had to do something with system resources and the app moving to background. I just had to save the inital time and pauses as a bundle and load them when the app is started again. Thank you everyone!
I'm no Android expert, but I'm guessing that the reason why your AsyncTask gets cancelled is because the OS, being a battery powered OS, is deciding that a long running background task is a bad thing for battery consumption.
Having your program run a background thread for years is going to be a big disappointment for your users who will wonder why their mobiles run out of juice within a couple of hours. I suggest finding another way of doing your time measurement. What's wrong with using the device's real time clock?
I see little point in trying to update a GUI once every millisecond. The OS isn't refreshing the screen at that rate anyway, and no user on earth is going to notice anyway. Plump for once every 40ms at most.
And then there's the matter of accuracy. There's no point trying to measure time with millisecond precision on a device like an Android mobile over periods of hours, never mind days or months. Left alone the clocks and oscillators will be wrong by several seconds a day. The best one will be the real time clock, but even that is going to be pretty poor (they always are). Android is probably doing an NTP updated a couple of times per day, so there will be brief periods in a day when the local clock is close to being accurate (but even then it won't be millisecond accurate).
So even if you do manage to measure time with millisecond precision over months the answers you'll be displaying to the user are going to be wrong by several seconds. You'll be lucky to get within minutes of the actual elapsed time.
If your goal is just to have a stopwatch display rapidly updating when the application is in the foreground, just loop reading the real time clock and calculate/display the time since the stopwatch was started. Don't bother doing anything in the background, just sleep. When your app becomes foreground again resume the loop; the device's real time clock will have been ticking away all the time you're app is asleep, allowing you to calculate and display the time difference. This will be a lot simpler than trying to have a long running background thread, and it will also be more accurate than any other way you might choose (though still not millisecond accurate).
Related
I'm trying to return time in milliseconds between both iOS and Android devices. I was hoping that since most devices sync their time with a networked server, they would be the same. However, I'm noticing they are not precisely the same.
I'm using this method for iOS:
[[NSDate date] timeIntervalSince1970]
and this for Android:
System.currentTimeMillis()
Is there a better way to try to return the same exact time across devices? I'm noticing these values can be off from each other by up to 2 seconds depending upon the Android device.
The use-case for needing this synchronized time is to display a looping animation that is also synced across the devices. So the animation would need to start at the same time, perform its animation for a set duration, and then loop again.
Thanks for any help.
You'll never get exactly the same time. The problem is that clocks aren't perfect, and that they aren't always synched to exactly the same time source at the same rate. Even if you synch to the same time source, the latency between when they process update messages will make a difference between them. 2 seconds is actually pretty good.
Time is tricky. Take 2 devices in perfect synchronimity. Fly from the US to Europe with one of them. They're no no longer in synch, and both are right- the general relativistic effects of traveling at high speed means one is now several milliseconds older than the other.
Basically what you want isn't going to happen. You'll have to settle for close enough. Although if you post why you need them so synchronized maybe we can give you some ideas.
I am working on a timer application (it's my first app to try and learn the ropes). While the timer is running, I want to offer the user the ability to prevent the screen from locking.
Since the screen is always displaying something (and refreshing the clock every second), what would the performance penalty be for doing this? The only things active on the screen are the timer (black background with just the running time) and "split" and "stop" buttons? I am mostly concerned with the battery life of the phone; e.g. if this were a long-running timer job (let's say long-distance running with split times).
I have used both an iPhone and an android for running apps in the past. The first iPhone versions couldn't 'lock' the screen because it disabled the GPS too. Leaving the screen on, even with minimal backlight, absolutely ruins battery life, because the backlight and screen-refresh operations are quite expensive. Battery life went up from ~30 minutes to ~5 hours when running with the screen off.
There are some innovative solutions to this for runners, for example RunKeeper (and I'm sure most of the other ones too) has an option to fade the music out and give you updates on your stats every n minutes.
Im implementing my own double tap zoom for my OpenGL ES app and am having issues with System.currentTimeMillis(): It seems like when the main thread gets a little busy, it isnt as accurate. 2 taps 200ms apart will show as 600ms apart. What is the most reliable clock to use in Android? I know theres quite a few.
The System.currentTimeMillis() call is quite accurate. The problem is likely that your handler for the tap isn't firing immediately, but because of the load is delayed a few hundred ms.
In the app I'm writing I have a bunch of stats which I want to display for the user.
The stats include when a specific module was last run, when it will be run next, when the last communication with the server was made and then the next one is going to be.
As well as this there are stuff like memory usage (simple memory usage, not measuring the actual usage).
The memory usage etc can be updated every few seconds so that not a problem the but the times needs to be updated every second at least (for counters).
Since running every second (or even with 500ms period) results in irregular updates/skipped seconds I now run it at 300ms period.
I did notice however that my app began to lag when starting.
After some profiling it turns out it's the views that need to resize that is taking 70% of the time and the string formatter (for formatting the counter) takes pretty much the rest.
Apart from the CPU being used I see a lot of allocations, every few seconds I see a GC_CONCURRENT in the logcat.
Any tips on solving this efficiently?
Can you restructure it in a way so that the fiews require less resizing? Eg: set the width of your element to fill_screen or a DP size that is bigger than the longest string size
I solved the problem by writing my own timer that sleeps in short increments and only updates the view when a full second has passed.
This way the fire interval will be [period, period+sleepTime) which is acceptable when you choose a short sleepTime.
I've also changed so it says "5 minutes ago" and I have two timers, one that fires every minute and one that fires every second.
I have some trouble achieving adequate real-time performance from my application and wondering if I've architect-ed it sub-optimally. The requirement is for the application to play a sound and draw a line on a Canvas at a user specified time interval.
I have a Thread that sleeps for the user-specified time interval, wakes up and uses a Handler and Runnable to do the required drawing and sound playback. When I run the application, the beat is steady sometimes, but other times, you can see the effect of GC and random warning conditions from the AudioFlinger.
Is having a Timer thread post back to the GUI thread via Handler/Runnable the best approach? Is there something I can do to bump up the priority of my app while it is visible so that other apps and Android activity are less likely to interrupt it? Do I need to use the NDK to access real-time features not present in the Java API?
It sounds like what you want to have going is a game loop. There are many tutorials out there on creating game loops with more consistant timing that just sleeping, for example simple java android game loop. You might try searching based on that term, see if it helps.
Also when trying to create real time applications (as in constantly dynamic applications not scientific real time system) you would want to avoid to let the garbage collector run. This takes some time and can be perceived as lag. So don't create objects you need to dispose immediately etc.