Exception: ViewLoop is not the current active page

Hi,

I just implemented a ViewLoop, and on my watch (not the simulator) I get this exception when switching views. It seems to happen after the view is switched, because the visually the view still changes.

Exception: ViewLoop is not the current active page
Stack: 
  - pc: 0x100026b9
    File: 'D:\Projects\EVCC Garmin\evcc\source\EvccViewLoopDelegate.mc'
    Line: 21
    Function: onNextView
  - pc: 0x30003640

My code looks like this, line 21 where the exception occurs is the changeView call.

function onNextView() {
    try {
        _viewLoop.changeView( WatchUi.ViewLoop.DIRECTION_NEXT ); // this is line 21
        return true;
    } catch ( ex ) {
        EvccHelper.debugException( ex );
        return false;
    }
}

Has anyone seen this before?

  • My app has a timer that makes a web request, and requestUpdate is called in the onReceive function, and only there.

    However, my logs clearly show that onUpdate is called twice after onShow, and before my onReceive gets called. Under normal circumstances, in the second onUpdate getCurrentView returns a value for the first time, but after the timeout, the onUpdate call is repeated again and again (without requestUpdate) and getCurrentView stays null.

    Here are the logs, first the normal case:

    18.5.2024 17:12:55: ViewLoopFactory: getView
    18.5.2024 17:12:55: **** currentView is null
    18.5.2024 17:12:56: Widget: onLayout
    18.5.2024 17:12:56: **** currentView is null
    18.5.2024 17:12:56: Widget: onShow
    18.5.2024 17:12:56: **** currentView is null
    18.5.2024 17:12:56: Widget: onUpdate
    18.5.2024 17:12:56: **** currentView is null
    18.5.2024 17:12:56: Widget: onUpdate
    18.5.2024 17:12:56: **** currentView is not null
    

    And here the course of events after the timeout:

    18.5.2024 16:52:52: ViewLoopFactory: getView
    18.5.2024 16:52:52: **** currentView is null
    18.5.2024 16:52:52: Widget: onLayout
    18.5.2024 16:52:52: **** currentView is null
    18.5.2024 16:52:52: Widget: onShow
    18.5.2024 16:52:52: **** currentView is null
    18.5.2024 16:52:52: Widget: onUpdate
    18.5.2024 16:52:52: **** currentView is null
    18.5.2024 16:52:53: Widget: onUpdate
    18.5.2024 16:52:53: **** currentView is null
    18.5.2024 16:52:53: Widget: onUpdate
    18.5.2024 16:52:53: **** currentView is null
    18.5.2024 16:52:53: Widget: onUpdate
    18.5.2024 16:52:53: **** currentView is null
    18.5.2024 16:52:53: Widget: onUpdate
    18.5.2024 16:52:53: **** currentView is null
    18.5.2024 16:52:54: Widget: onUpdate
    18.5.2024 16:52:54: **** currentView is null
    18.5.2024 16:52:54: Widget: onUpdate
    18.5.2024 16:52:54: **** currentView is null
    

    All of these onUpdate calls happen independent of my web request - initially my onUpdate operates on data from the persistant storage.

  • If the primates sample (with an added glance view) doesn't exhibit this issue, and your app is based on that sample, you want to look at what's different.

  • THANKS for reminding me of Primates. Seems here also the temporary erratic behavior of the timeout interfered as well, but now I can consistently reproduce the issue with my modified version of Primates.

    I already created a bug report (hope I did it in the right place) and uploaded my Primates project and two videos showing the issue with Primates.

    https://forums.garmin.com/developer/connect-iq/i/bug-reports/bug-viewloop-is-not-the-current-active-page

    In any case, I think the issue is not limited to ViewLoop. Generally when the issue occurs, WatchUi.getCurrentView() returns null. ViewLoop is just affected because it checks against the current view, but any other code that relies on the current view would not work as well.

    I'll be looking for a workaround next - maybe calling WatchUi.switchToView with the ViewLoop if getCurrentView is null would help.

  • Unfortunately neither switchToView nor pushView seem to work in this situation. I tried with the existing ViewLoop, a new ViewLoop and a completely different simple view, but both functions always return null, the app is stuck with the initial ViewLoop and getCurrentView continues to return null as well.

    So right now I cannot figure a workaround for this. :-(

  • So for a "workaround" I'll simply abandon the ViewLoop implementation and do it on my own, using WatchUi.switchToView. While replacing the ViewLoop after the timeout using switchToView did not work, if I do not use a ViewLoop from the beginning, switchToView also works after the timeout, it does not seem to be affected by this bug.

    Already got the basic implementation to work in my app, only the visual indicator is missing. I'll take the one from the Primates app as baseline and will try to adapt it a bit to the current look&feel of the Garmin widgets.

    I was not that happy with how the ViewLoop looked visually anyway, so I'll take this bug as an opportunity instead of a nuisance. ;-)

  • Sadly I can confirm I have a similar issue. ViewLoop seems broken whenever a timeout occurs, for widgets at least. I have also encountered another issue that seems hard to reproduce but it happens from time to time (I have been unable to trigger it from within the simulator): When I open the widget from the glance and then immediately try to scroll, sometimes it renders the ViewLoop "page indicator" and then the IQ symbol with a exclamation (indicating crash). The ViewLoop page indicator still in view however.



    Also from time to time when I open my widget after some use (without crashes or timeouts), the ViewLoop page indicator starts at the opposite side as the simulator (or as when opening the app when the watch has rebooted). When this happens, generally scrolling also seems to lead to a crash. This seems unrelated to timeouts as far as I can tell as I had this happen at least twice without a timeout happening in the widget, so it is very hard to tell what is causing this. Log files don't seem to contain anything useful for me at least.

    This is rather frustrating and I would like to know why this happens so I can use the Garmin builtin ViewLoop instead of having to provide a sort of "ViewManager" class myself that manages view switching (what I do now, but that is prone to errors on my side and I would like to avoid that).

  • It also seems that long-pressing the back button to "jump" to the menu screen from a view that is not the first view in the ViewLoopFactory causes a crash too... it is also really hard to verify if I made an implementation mistake somewhere, or if there is something else going on.