Occasionally onBackgroundData is not invoked when background.exit()

Hi, I have a watch face that is using makeWebRequest in a background to get data from a web server. Occasionally, the wath face stops update the data in the UI, this usually happens after connecting it to the USB, or after exiting the morning report, and sometimes it just happens.

Whar Ican see in the log files is that the background process fires up as it should, it makes the webRequest and the callback function gets invoked with the data and responseCode. In the web request callback function function readResponse(responseCode, data) as void I can see that I got good data and I call Background.exit(myData);

When things are working as they should, the on BackgroundData(data)function gets invoked and I get the data to the foreground so I can update th UI. 

Here is the log entries when it works:

T:15:19:33 app:onStart
T:15:19:33 in getServiceDelegate
T:15:19:33 Background Service initialize()
T:15:19:33 in onTemporalEvent
T:15:19:33 in getData
T:15:19:36 in readResponse: [<my data here>] 200
T:15:19:36 in readResponse: bg_exit with data
T:15:19:36 in onBackgroundData: [<my data here>]

Her is the logging when it doesn't work:

T:14:41:32 app:onStart
T:14:41:32 in getServiceDelegate
T:14:41:32 BG Service initialize
T:14:41:32 in onTemporalEvent
T:14:41:32 in getData
T:14:41:35 in readResponse: [my data here] 200
T:14:41:35 in readResponse: bg_exit with data
T:14:41:35 app:onStop

When the problem starts, the only way to get it working again is to restart the watch, or toggling to another watch face and then toggle back. 

The problem not that the background process fires, it always does, the problem is that the onBackgroundData in the main app does not get called when I do Background.exit() from the background

I have completetly run out of ideas of things to test. Anyone seen this before? could it be something happening in the system that disconnects the background process from the app, or something? I'm clueless. 

I have no crashes and no crash file on the target. 

I can of cours edump all my code here but wanted to see if anyone had any idea first. 

as always, thanks for your help. 

 

  • Indeed, I posted about it about 2 years ago (maybe even there's a bug report)

  • Yeah, I saw your post and read through the whole thread. My problem seems a bit different though. It cannot be reproduced in the sim.  On target it works, like, 98% of the time but occasionally it just stops working for no obvious reason and the only way to get it to work again is a watch restart or toggle to another watch face and back. 

    The log files clearly indicate the background process runs until termination until the background.exit() call. I am sure it exits with data but for some reason the onBackgroundData function never gets invoked. It's a complete mystery to me. 

    I have been able to reproduce on my Epix gen 2. And I suspect some of my users are having the same issue, what usually happens is that they un install and re install the WF, before reaching to to me for support. 

    I don't really know what else I can try at this point.  

  • I had this issue. It was a REALLY strange one. I had a bug in which I sent the screen width in onLayout(dc) and used that in compute(). When compute ran first, I multiplied by null. Obviously a crash situation, that occured right at boot time, before onLayout(). For some reason the crash occured AFTER my Background Process ran successfully and performed the exit() but before the onBackgroundData() ran! No LOG file was produced. I finally found some evidence in ERA that helped me solve this. I traced the problem to that BG/FG interface using some prints. So weird, but finally solved.

  • Hi Thanks for replying. I did not think of that scenario as no traces to be found in the log files. However, my problem ocurrs later, usually after the watch has been disconnected from the garmin connect for a while and very randomly. 

    You mentioned you found evidence in the ERA, I am not sure I know what ERA is. Is it another crash log? 

    best regards

    Fredrik 

  • hi again   So if I understand your post correctly; you assigned a value to a (global) screen-width variable in onLayout(), and used that variable in compute(). If that is the case, I dont understand why the app would crash. Is not onLayout() always called before compute(), or can we not take that for granted? 

    In my watch face app, I have assumed onLayout() has always been called before onUpdate(). if not, I may run into the same problem as you. However, one would think that the entire FG process would crash and stop updating. My watch face continues to update the time on the screen (done in onUpdate()) but it does not receive any data from the bg process although the bg process exits with data. 

  • Logic says that onLayout has to be called before the 1st onUpdate, however not 100% sure if it's also before the 1st compute

  • The background can run before the main app is even started if you've turned off the device, let it sit for longer than the temporal event, and turn it back on.

    Let's say you register a temporal event for every 5 minutes. That does not restrict it from running after you close the main app, in fact that's one of the reasons to use a background - to collect data when the main app isn't running. 

    So in the case of a data field, the background keeps running after you are done with the activity it's used in, unless you disable temporal events.

    Watch faces are kind of a special case,  Let's say you have two installed, where both have a background service.  Only the background for the "active" watch faces runs - the one you see running.

    So, nothing in the background should depend on the main app running first. and the data seen in onBackgroundData may have been generated before the main app has been started,

    The sim doesn't really show you what can happen with a real device in some cases.

  • Since when background app calls onLayout and onUpdate? BTW he explicitly wrote watchface.

  • If you previously registered a temporal event and power off and on the device, the background could run a number of times before your main app's onLayout/onUpdate is called.  And for a watch face, it can also run before onLayout/onUpdate.

    Have you seen this?  https://developer.garmin.com/connect-iq/connect-iq-faq/how-do-i-create-a-connect-iq-background-service/#howdoicreateaconnectiqbackgroundservice

    Here's an old thread started back when backgrounding started..

    https://forums.garmin.com/developer/connect-iq/f/discussion/5287/very-simple-sample-of-a-watch-face-with-a-background-process

  • ERA is a powerful facility in which a crash can be automatically reported when your app crashes out in the wild running by others. in VSC for example, CTRL-SHIFT-P and see Open ERA Viewer. It'll tell you the line of code and cause of the crash.