I need to update my WatchFace view only when settings change. How do I do it?

Hi I'm trying to implement settings on my watch face but I don't want to load settings on every onUpdate() but just onLayout() or when they changed.

My code works in the emulator but it's not working on a device.

Here is how I implemented it:


class MyApp extends Application.AppBase {
    hidden var _view = new MyView();
    ...
    // Return the initial view of your application here
    function getInitialView() as Array? {
        return [ _view ] as Array;
    }
    // New app settings have been received so trigger a UI update
    function onSettingsChanged() as Void {
        _view.onSettingsChanged();
    }
    ...
}
    

class MyApp extends Application.AppBase {
    hidden var _view = new MyView();
    ...
    // Return the initial view of your application here
    function getInitialView() as Array? {
        return [ _view ] as Array;
    }
    // New app settings have been received so trigger a UI update
    function onSettingsChanged() as Void {
        _view.onSettingsChanged();
    }
    ...
}

Could you help me?

EDITED - January 14th, 2023:
[SOLVED]

To make the code example simpler, and focused on the investigated problem, I omitted here in this post some lines of my full code.

Unfortunately, the real problem was in one of those lines, where the _loadResources() method was called.

As _psx_ pointed out, the problem with this is the attempt to load resources (a storage operation) outside of onLayout().

Also, _psx_ also pointed out the problem with instantiating my View outside of my App class's getInitialView().

Below is my incorrect code, still simplified, but with these problems (red lines):


class MyApp extends Application.AppBase {
    hidden var _view = new MyView();
    ...
    // Return the initial view of your application here
    function getInitialView() as Array? {
        return [ _view ] as Array;
    }
    // New app settings have been received so trigger a UI update
    function onSettingsChanged() as Void {
        _view.onSettingsChanged();
    }
    ...
}

class MyView extends WatchUi.WatchFace {
    private var _lastMinute = 0;
    private var _propertiesChanged = false;
    ...
    function onLayout(dc as Dc) as Void {
        _loadResources();
        _loadSettings();
    }
    
    public function onSettingsChanged() as Void {
        _loadResources();
        _loadSettings();
        _propertiesChanged = true;
        requestUpdate();
    }
    function onUpdate(dc as Dc) as Void {
        var clockTime = System.getClockTime();
        if ((clockTime.min != _lastMinute) || _propertiesChanged) {
            _propertiesChanged = false;
            _draw(dc);
        }
        _lastMinute = clockTime.min;
    }
    ...
}

And below is the correct code:


class MyApp extends Application.AppBase {
    hidden var _view;
    ...
    // Return the initial view of your application here
    function getInitialView() as Array? {
         _view = new MyView();
        return [ _view ] as Array;
    }
    // New app settings have been received so trigger a UI update
    function onSettingsChanged() as Void {
        _view.onSettingsChanged();
    }
    ...
}

class MyView extends WatchUi.WatchFace {
    private var _lastMinute = 0;
    private var _propertiesChanged = false;
    ...
    function onLayout(dc as Dc) as Void {
         _loadResources();
        _loadSettings();
    }
    
    public function onSettingsChanged() as Void {
         // REMOVED _loadResources()
         _loadSettings();
        _propertiesChanged = true;
        requestUpdate();
    }
    function onUpdate(dc as Dc) as Void {
        var clockTime = System.getClockTime();
        if ((clockTime.min != _lastMinute) || _propertiesChanged) {
            _propertiesChanged = false;
            _draw(dc);
        }
        _lastMinute = clockTime.min;
    }
    ...
}

The full source code can be seen here:
https://github.com/eldes/presbyopia-watch-face