Right way to share variables/data with background and foreground code?

In my app I have state shared with background code (temporal event handler and callbacks) and non-background code (update, draw etc. handlers).

Currently I'm using `getProperty` and `setProperty` to access that state in background and foreground code, but as I understand it this is not the right way to do it. I'm wondering how to best do it.

For the state that are only used in background code I can add `(:background)` to the variables and that should work? (I haven't tried this)

Normal `var`s work with the foreground code.

What if I want `var`s that will be updated and read by both the background and foreground code? What is the right way to implement this?

  • The main app and background service each have their own copy of a variable, so

    (:background) var abc=false;

    aren't the same thing in the two processes.

    if in onTemporalEvent() you have

    abc=true;

    The main app's value of abc doesn't change and remains false, but in the background service it will see it as true.  And in the background, it will only be true until the background service ends (30 seconds at most) and doesn't carry over the next time the background runs.

    Also, understand that the background can run when the main app isn't running.  Say in a watch face or widget, there's a temporal event set for every 5 minutes.  The user starts a run activity, and runs for an hour.  The background can run 12 times during that time, and its man app doesn't run at all.

    For me, if I have something the background wants to pass back to the main app, I use Background.exit() and then it's seen in the main app in onBackgroundData.  The main app, by default, will only see what's passed back the last time the background ran. but the background can use getBackgroundData to get what's currently queued for the main app and append/merge that with what's currently returned.

  • can they communicate via a property?

  • I would use Application.Storage not Application.Property.

    In a background service, I'll read from both, but pass infro from the background using Background.exit().

    In the case where the background is doing something like a makeWebRequest, I'll pass back the dictionary, or the error if one occurs, and then in onBackgroundData, use "Instanceof" to see what I got, and in the event of a number, I can then use that to display an error in the main app.

  • How do you pass data from the main app to the background?

  • You can put it it Application Storage and habe the background read that.  I do that with lat/lon for example.  But your main app has to run at least once before the background runs to set the data.

  • I don't know if it's the textbook solution, but I use Storage to write data in background and then onStorageChanged in foreground to read the data. With Background.exit(result) I transmit the success status of my background call, so in case my background call failed, I will get that info in the foreground, too. 

  • Is there any way to pass a value from FG to BG for devices that don't support API 3.2.0 (can't access Storage from a BG process)?

  • If you can't do a setValue() in the background service, the only option is to use Background.exit() but there the amount of data you can pass is limited, so you need to limit what you return.

  • Thanks Jim. I get that. I need to pass something the other way. FG to BG. I need to inform the BG process of something. Not using Storage. I might have to do something really sketchy like using the clock time when I run the BG process and if it runs when the ToD clock is in the first half of a minute do X, vs second half of a minute do Y. Ugh. Any other thoughts on conditional execution in the BG process based on something in the ForeGround?

  • You can read the data in the background service.  This is how a background can get things like an APIKey.

    you need to use the older calls like getProperty() on decices that don't support the new calls like getValue()