https://github.com/facebook/react-native/issues/167
"I wanted to start a discussion about the timers and an API that exposes the capabilities of the system timers. A couple of things I noticed were that the timers use CADisplayLink on the main thread and also listen to the UIApplication state notifications. To my knowledge this works well for timers that are coupled to the UI (requestAnimationFrame comes to mind, there may be other uses). I'd like to discuss timers that do other work e.g. interact with the event loop or schedule background tasks, and how they co-interact.
Event loop timers seem to fall into two categories - those that run at the end of the current loop and those that run right after. This is like process.nextTick and setImmediate. These aren't too hard to implement though there are a couple of gotchas like warning if a process.nextTick handler endlessly schedules itself before blowing the stack. I would also expect both of these timers to run even if the app is inactive or backgrounded (e.g. say you get a network response while the app is backgrounded and schedule some work to run soon after - it should run in the background).
Background task timers (setTimeout, setInterval) raise a couple of questions like the semantics of a zero-ms timeout. I would also propose that these run in the background as well to address the use of running code that does not need the app to be foregrounded. And, if the app is backgrounded there is little harm in running UI code anyway -- in cases where it does matter, the timer handler can check the UIApplication state.
Background task timers that repeat are also good candidates for energy optimization. One thing that OS X systems do is coalesce timers where possible, partly aided by the programmer providing a tolerance value. If many running apps schedule timers that can overlap within their respective tolerance windows, the system may wake the CPU just once to run all of those tasks together." - @{ide}
Having a background timer that won't stop when the app goes to sleep will really be useful! At the moment, I have to implement in native a service for continuous/repetitive background tasks.
@acctforpp: can you share how you do these background tasks?
@Rob Dunham Lingstuyl: basically you use Android's AlarmManager to set up a native timer, and on every interval send over the event to JS as mentioned in this doc. You can then run the processes in JS thread. https://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript
+1. I had to leave out a local notification feature for our event app because this isn't available. Would love to have this!
For my own usage I am working on an app that has scheduling and reminder needs. If the app is not in the FG or not running then I still need to notify the user of an event. I can partially work around this if the user is connected to the internet by way of having the server track the timing of events and sending push notifications. If the user is not connected though the app becomes much less usable.
Check out this component https://www.npmjs.com/package/react-native-background-timer
Thanks for the link. I did happen to check it out a few days ago and filed an issue. I've done some research on this topic and providing a common interface for android and iOS will be a challenge for anything other than very narrow functionality. Android has quite a few options for background execution: https://plus.google.com/+AndroidDevelopers/posts/GdNrQciPwqo
iOS appears to have fewer but none are immediately obvious as overlapping directly with the Android options.
iOS also wants you to declare what type of background process you are running:
This component works in a simulation. Thank you!!!
I am writing VoIP app, so background execution is super important.
oh no this is super needed. After I ported my webApp in two days-- Well yes just two days, but working around 20 hours a day-- i was just as excited how I would get the background execution for free... Well nothing is for free! Come on guys this is feature is crucial, isn't it? my use case is motion/sensor monitoring app.
I think it would be helpful if you and @oney were to comment on what timer functionality you want from both platforms... and/or go more in depth into what functionality you are trying to implement... see my post for all the flexibility the two platforms have... which is seemingly built in to hit different use cases
Just to want to add my voice to this feature request. We use beacons and handle their events in JS in order to send them to our API. It's really frustrating that whenever we try think about implementing retries/throttling/debouncing we can't because it isn't supported in background mode. This kind of location tracking is dependant on the app running in the background so it requires a lot of workarounds for us to support things such as retrying failed requests (with delay) when network connection is not available.
We could handle some of this natively, but it kind of kills a lot of the benefit of react native being platform agnostic, as well as there being lots of JS tools available to support timer based behaviour.
https://www.npmjs.com/package/react-native-background-timer
be aware, this timer wont work when app is inactive over 180 seconds because of the sleep
try alarmmanager in Android and use RCTDeviceEventEmitter to send timer event from Java to JS
I did a library for Android where you can schedule a repeating task that periodically will execute JS code in the background even though the app was killed or the phone was rebooted. It uses Android's JobScheduler and React Native's HeadlessJS. To get it working for iOS I would need Headless JS to be ported to iOS. The timer is not very exact (due to power saving) but it works for our use case.
You can quite easily do the job using Android Services, or Wakelocks. The JavascriptCore get loaded only when the application is launched for the first time, so while maintaining a service, the JS Context is not lost. By doing such you can maintain timers and network activity while the app is "closed". But React views are getting destroyed when the app closes so careful, don't put your business logic in your React components.
To @Anthony Benkhebbab 's point: I started using Headless JS for background execution on Android but noticed that the "main" app with respect to non-UI aspects was still functioning, could even continue to persist to the redux store. What does Headless JS do that the main/UI app can't?
@Bren W: as I said the JS context is not getting destroyed while there are some services up and running. On android, once your app goes to background it's eligible for being destroyed by the OS to free memory required by an other active application (e.g music, videogame..). This is when your JS context get lost. To overcome this, Headless JS uses a Service (that can run even through the app is in background, or even closed) and acquire a wakelock for it to operate even when the phone is locked. As the service can only start after the app itself started, and as the JS Context is kept until the main activity itself gets destroyed, your JS code can still run, your redux store is still alive.
I think the main error is to think that when your app goes to background/when you closes the app, the JS context gets destroyed. I don't know the details, but it is not really until the whole process is finished.
@Anthony Benkhebbab: Thanks, that explains it. So while I am currently seeing activity in the UI app even when it goes to the background (not views, but business/redux logic), there's no guarantee that it won't be destroyed by the OS at some point, to free up resources or what not. And of course not to mention wake lock. So I will keep all of this logic that needs to run in the background in headless js.
@Bren W: That's exactly the point on Android at least, you have no idea when the OS will destroy the app, the best you can do is put a maximum of red flags for the OS to know how important your app is (so far i've found STICKY service, startForeground, and ignoring battery optimizations when API > 23)
By the way watchout for phones with API > 23 running Stamina modes and stuff to optimize battery usage. I've taken quite a lot of time to figure out my app was getting closed due to battery optimizations.
@Anthony Benkhebbab: I have not had any luck with startForeground, STICKY and API > 23. setInterval still stops when the app loses focus. Example code - https://github.com/rgstephens/RNForegroundExample
It is much needed feature plus it should allows you to schedule background task at specific time.
Yes, it will be very helpful if we can run task in background periodically
I can't believe we don't have such a thing yet ! :(
+1 Any solution? I need this feature to finish my project.
This would be a very useful feature -- a solid implementation of something like a Pomdoro app (https://github.com/exponentjs/pomodoro) isn't possible at the moment because if the app sleeps, timer execution pauses immediately. This is one of many use cases!