Error: Out Of Memory Error when installing the beta version of my watch face

Hi community, I'm testing my Watch Face from a Beta version installed from IQ Connect. After the installation, I can see that for some reason the installation date is not being store properly in the Application.Storage. 

This is my code:

class MyWatchFaceApp extends Application.AppBase {

    function initialize() {
        AppBase.initialize();
    }
    
    ...
    
    function onAppInstall() as Void {
        storeInstallationDate();
    }

    function onAppUpdate() as Void {
        storeInstallationDate();
    }

    ...

    hidden function storeInstallationDate() as Void {
        var epochInstalledOn = Application.Storage.getValue(INSTALLED_ON_DATE_STORAGE_KEY);
        if (epochInstalledOn == null) {
            var epoch = Time.now().value();
            Application.Storage.setValue(INSTALLED_ON_DATE_STORAGE_KEY, epoch);
        }
    }
}


In the simulator, I can see that is working all the time. I'm deleting the watch face by pressing Simulator > File > Delete All Apps before each run, and all the time I can see the installation date being stored correctly, like below:



So, I have checked the watch logs and I found this:

---
Error: Out Of Memory Error
Details: Failed loading application
Time: 2024-10-15T20:26:11Z
Part-Number: 006-B3291-00
Firmware-Version: '27.00'
Language-Code: spa
ConnectIQ-Version: 5.0.1
Store-Id: 3ff25bd7-09bf-412d-ae93-2bd2e23b1ce4
Store-Version: 1
Filename: EAFK2606
Appname: MyWatchFace


 And the .SET file has a size of 198 bytes:



I've al so compared the simulator files and the olny thing I see a bit weird is that in the DATA folder of the simulator the files .DAT and .IDX exists, but not in the Watch's DATA folder.

Any take on this? What can be the issue here?

Top Replies

All Replies

  • how does the memory usage (and peak memory) look in the sim on the same device?

  • To use onAppInstall, onAppUpdate, you need to have the background permission set, but that also means you want to annotate things for the background, or it will try to load your entire app when the background runs.

    In the code you posted, before the class definition for AppBase (right before line 1), try adding 

    (:background)

    That way only your AppBase gets loaded when the background runs

  • Hi

    To answer your question, this is what I have in my memory usage:



    I think those numbers are ok for my understanding.

    Do you see something wrong there?

  • Hi

    I've tried the approach you suggested, and now my code looks like this:

    import Toybox.Application;
    import Toybox.Lang;
    import Toybox.WatchUi;
    import Toybox.Time.Gregorian;
    
    (:background)
    class MyWatchFaceApp extends Application.AppBase {
    
        function initialize() {
            AppBase.initialize();
        }
    
        // onStart() is called on application start up
        function onStart(state as Dictionary?) as Void {
        }
    
        // onStop() is called when your application is exiting
        function onStop(state as Dictionary?) as Void {
        }
    
        function onAppInstall() as Void {
            storeInstallationDate();
        }
    
        function onAppUpdate() as Void {
            storeInstallationDate();
        }
    
        // Return the initial view of your application here
        function getInitialView() as [Views] or [Views, InputDelegates] {
            if(!Helpers.isAmoled() and Toybox.WatchUi.WatchFace has :onPartialUpdate) {
                return [ new MyWatchFaceView() as Views, new MyWatchFaceDelegate() as InputDelegates ];
            }
    
            return [ new MyWatchFaceBIPView() ];
        }
    
        // New app settings have been received so trigger a UI update
        function onSettingsChanged() as Void {
            WatchUi.requestUpdate();
        }
    
        function getSettingsView() {
            var settingsMenu=new MyWatchFaceSettingsMenu();
            return [settingsMenu as Views, new MyWatchFaceSettingsMenuDelegate(settingsMenu) as InputDelegates];
        }
    
        hidden function storeInstallationDate() as Void {
            var epochInstalledOn = Application.Storage.getValue(Helpers.INSTALLED_ON_DATE_STORAGE_KEY);
            if (epochInstalledOn == null) {
                var epoch = Time.now().value();
                Application.Storage.setValue(Helpers.INSTALLED_ON_DATE_STORAGE_KEY, epoch);
            }
        }
    }
    
    function getApp() as MyWatchFaceApp {
        return Application.getApp() as MyWatchFaceApp;
    }


    I tried, and uploaded and published a new beta version, however after installing it I got the following error in the logs:

    ---
    Error: Illegal Access (Out of Bounds)
    Details: 'Failed invoking <symbol>'
    Time: 2024-10-16T16:59:03Z
    Part-Number: 006-B3291-00
    Firmware-Version: '27.00'
    Language-Code: spa
    ConnectIQ-Version: 5.0.1
    Store-Id: 3ff25bd7-09bf-412d-ae93-2bd2e23b1ce4
    Store-Version: 4
    Filename: EAGG5047
    Appname: MyWatchFace
    Stack: 
      - pc: 0x1000004c
      - pc: 0x10000021


    Now it's a different error, not "Out Of Memory" anymore, which means that the (:background) did work.

    Can this new error reside in my storeInstallationDate function?

  • , That was very helpfull, I ended up doing the following:

    1- I scoped all my resources(font, string, bitmap and the layout) as "foreground" since I ain't using it in my base class and thus save memory.

    2- I decorated also with (:background) all the global and external variables that I'm using in my base class, like for instance the Helpers class, since I'm using Helpers.INSTALLED_ON_DATE_STORAGE_KEY.

    So, I've published a new beta version and this time finally worked. I'll monitor it a bit more to ensure all is good.

    As always, thank you my friend for the great help.

    /Juan