Glance View and Background process - Design Pattern needed

Hi, I have one widget where I can't get the glance view reliably visible. I haven't found the problem currently but I am not far away. One thing which could make problems is that backgrounding may interfere with glance since one function isn't annotated with glance. My hypothesis: As soon as the background is triggered once, the glance view is gone. 

I have coded following:

var myTimer;

(:background)
class BatteryInfoApp extends App.AppBase {


    function initialize() {
        AppBase.initialize();    	
    }
    
	(:glance)
	function getGlanceView() {
        return [ new MyGlanceView() ];
    }     

    function getInitialView() {
    	if(Toybox.System has :ServiceDelegate) {
    		Background.registerForTemporalEvent(new Time.Duration(300));
    	}
		initBatData();
        return [ new BatteryInfoView(), new batteryInfoDelegate()];
    }

    function onBackgroundData(data) {
		initBatData();
        batData.checkBgData(data);
    } 

	function initBatData() {
    	if (batData == null) {
    		batData = new batteryData();
    	}
	}

    function getServiceDelegate(){
        return [new BgbgServiceDelegate()];
    }

initBatData isn't annotated with (:glance). As soon as I do so (for trial reasons) I get an error as soon as I am within the glance view on the watch and the background process is triggered, since I haven't annotated the class batData with (:glance). I could do that but I don't want since batData needs more mem. Is there any design pattern how to handle this? I don't need batData in the glance view...

If I don't annotate the initBatData() with glance, the sim works correcly always. But on the real watch I can see the glance view for a while before it is gone forever...

  • onBackgroundData can get called when in glance view or full screen.  That's something to keep in mind.  Also, based on the fdvice, live_updates could be true or false and there is a difference as how things look back on that.  The f6 pro, it's true, and the f6 (non-pro) false if you want to check that out.  

    Glance is limited to 32k, and that will include the background, so if your background uses 11k, that only leaves you with 21k for the glance view itself.

    What's the error you're getting and what's in the stack trace?

  • Hi Jim, as I said, I have only trouble on the real watch, not on the sim. The troubles are, that the coded glance view isn't shown, but instead the default glance view is shown. We had a discussion in your other thread. If this happens, the getGlanceView isn't calles at all. You advised me to write debug messages to check what's going on on the real watch and it turned out that the view isn't called. Very strange is, that the glance view is shown if you newly install the widget. But only for a very limited time. Then it's gone forever and the default glance view is shown again. The sim shows the glance view always fine probably since after a reload a cache is cleaned.

    My hypothesis is that it has to do with backgrounding. The glance view shows just normal as intended until the first time backgrounding cicks in. A value is written in the background process which, if the glance view is called via the main app, the onBackgroundData is called which causes the global variable to be set. But the class batteryData() isn't annotated with (:glance). I can't explain it more detailed, since I just speculating....

    Therefore I asked for a design pattern

  • From the API description:

    When the Background process terminates, a data payload may be available. If the main application is active when this occurs, the data will be passed directly to the application's onBackgroundData() method. 

    The question is: is the application active, when the glance view is displayed?

  • Yes.  onBackgroundData will get called.  And if  the glance/full widget isn't running, onBackgroundData will be called when the glace/widget starts.

    Could it be you don't see the glance because there's not enough memory to run it?

  • Jim, I believe so. It's too much memory or other stuff, since the class I create in the onBackgroundData is heavy. Maybe there are some code lines which can't be used in glance at all. The strange thing here is, that the simulator works pretty well.

  • Is there a design pattern for this? I need to store the background data to process it the next time I can create that heavy class...

  • OK, I have now two workarounds in place, but not checked whether they are working.

    First one: introducing a variable, called glanceViewIsRunning. The variable is set to true, in the getGlanceView() function and to false in the getInitialView() function. If set, the onBackgroundData stores the data temporarily in the object store and don't initialilze the heavy class. There is some coding around that but not too much.

    Second one: tagging the heavy class with (:glance), but I currently get a compile error:

    Error: Illegal Access (Out of Bounds)
    Details: Failed invoking <symbol>
    Stack:
    - initBatData() at C:\Users\User\eclipse-workspace\Battery Info\source\BatteryInfoApp.mc:43 0x10000126
    - onBackgroundData() at C:\Users\User\eclipse-workspace\Battery Info\source\BatteryInfoApp.mc:36 0x100000ef

    The heavy class does nothing special, just reading from object store, etc. This should make no problem in the glance view. The only speciality I use is a timer callback. Does this make the error message?

  • Hi Jim, the first implementation did work on the watch. Thanks for your support.