onUpdate Before Hide

I'd need an experiment to prove it, but it seems like the OS will call onUpdate just before onHide when a watch face is shutting down. I'd like a way to discern between an update when the app is shutting down and a "normal" update so I can avoid expensive drawing operations as the app is shutting down. This would help make the exit animations smoother. Has anyone else encountered this and come up with a solution? Thanks.
  • because you wouldn't have to worry, because the user wouldn't be looking.

    It sounds like he is trying to avoid doing animations on the watch face as it is sliding off the screen to view widgets.

    Since you are talking about the low-power mode functionality, it should be noted that it is entirely possible that the user would be looking at the watch face for an entire 10 seconds or more (when onEnterSleep() would be invoked).. especially for watch faces that show lots of information.

    I'd need an experiment to prove it, but it seems like the OS will call onUpdate just before onHide when a watch face is shutting down.

    For views within an application, the onHide() callback is invoked after the transition animation is complete, so there is no way to know (from within onUpdate) if this is the last call to onUpdate() for that view.

    View.initialize
    View.onShow
    View.onUpdate
    View.onHide


    I did some testing on my 920XT (w/ 3.20 firmware), and for watch faces, I don't see onHide() getting executed at all. Here is a trace of the calls made while using a test watch face...

    App.initialize
    App.onStart
    WatchFace.initialize
    WatchFace.onShow
    WatchFace.onUpdate
    WatchFace.onUpdate
    WatchFace.onEnterSleep
    WatchFace.onUpdate
    WatchFace.onExitSleep
    WatchFace.onUpdate
    WatchFace.onEnterSleep
    WatchFace.onUpdate
    WatchFace.onExitSleep
    WatchFace.onUpdate
    WatchFace.onEnterSleep
    App.onStop


    So, as far as I can tell, there is no way to know that this is your last call to onUpdate().
  • Former Member
    Former Member over 10 years ago
    It's sorta messy, but the only thing I can think of that might give you a chance to check for the button press. Add a delay loop into onUpdate

    function onUpdate(dc) {

    if(doLoop){
    loopFunc();
    return;
    }
    else if(isHiding) {
    return;
    }
    else {
    pauseTimer.stop();
    }

    // .....

    doLoop = true;
    }

    function loopFunc(){

    doLoop = false;
    pauseTimer.start(method(:requestUpdate),100,false);

    }

  • Thanks for the response, Travis. Actually I'm not trying to avoid animations but rather would like to keep my watch face from blocking when the exit animation is trying to start.
  • Sharkbait, that seems clever and we could hope for a more direct way, but that sort of approach seems like a possibility. I haven't thought it through all the way yet, however.
  • Have you considered something like setting your own timer (maybe every 15 minutes, as the images wont be changing that fast) for the expensive stuff in a timer callback, and then have onUpdate just update it on the display? I "think" you can set up your own timer in a watchface. but have not tried it.

    Doing something that's expensive directly from onUpdate (even every minute) could really impact the battery life.
  • Sharkbait, that seems clever and we could hope for a more direct way, but that sort of approach seems like a possibility. I haven't thought it through all the way yet, however.


    I don't think a watchface can catch button presses, but I may be wrong...
  • The earth is calculated dynamically rather than via a series of images. I'd considered that approach but it isn't possible to fit too many images into 64K, even at 1 bit-per-pixel. I wanted the earth to be oriented realistically, i.e. tilt as well as rotation from the perspective of the sun.

    Battery life isn't too bad since there is only a partial update of the earth each minute.
  • I don't think a watchface can catch button presses, but I may be wrong...


    I think what sharkbait was implying was to toss out the first update (just in case it is a button press), and then initiate a requestUpdate() afterwards to do the real work.
  • The earth is calculated dynamically rather than via a series of images. I'd considered that approach but it isn't possible to fit too many images into 64K, even at 1 bit-per-pixel. I wanted the earth to be oriented realistically, i.e. tilt as well as rotation from the perspective of the sun.

    Battery life isn't too bad since there is only a partial update of the earth each minute.


    What if from the timer callback, it had the dc, and from within the "expensive stuff" it put it on the display itself, and onUpdate just handled the simple stuff? You probably couldn't use layouts, and there would be some housekeeping involved, such as clearing the display and such.
  • What if from the timer callback, it had the dc, and from within the "expensive stuff" it put it on the display itself, and onUpdate just handled the simple stuff? You probably couldn't use layouts, and there would be some housekeeping involved, such as clearing the display and such.


    I'm not using layouts anyway in this case, but I'm not sure if it would be good to retain the dc in a class variable. Since the dc is passed on every onUpdate() cycle, it seems like it would be fair game for the OS to change it at any time. That is, I don't know if we have any guarantee of the object lifetime of the dc. Good thought, though.