Entire watch crashes after experimenting with custom fonts

Hi,

I introduced a new setting which let the user decide whether to use the system font or another one. After I set "the other one" in the settings, the entire watch crashes. The only way to get the watch running again was to connect it to the PC and delete manually the prg file.

Here is what I did:

https://www.dropbox.com/s/yestbbaqvg12hai/Hang.JPG?dl=0

If I leave the setting to system font the watch works well, but as soon as I use the customFont the entire watch hangs, shows a big triangle and just beeps on each key press. Any ideas what's going on?
  • Wouldn't say the reason must be the font...
    ...but to help some more information is needed!

    o which device(s) are you using?
    o what happens when your code is started on the simulator?
    o what happens when you remove the if font==1 line in your code?
    o and when you change fontHours to customFont in the drawText line?
    o are you sure customFont has got a value?
    o :
    o :

  • What do you see when you use the app settings editor in Eclipse?
    What type is the setting? Number, boolean, etc
    If Number, as you using the wrapper in the new Dev FAQ point #10?

    I suspect what's happening is in your code, you're using something that's not a font where a font is expected.

    So something like "myfont" is a null, instead of what you got from Ui.loadResource(Rex.fonts.<id>);
  • Wouldn't say the reason must be the font...
    ...but to help some more information is needed!

    o which device(s) are you using?
    o what happens when your code is started on the simulator?
    o what happens when you remove the if font==1 line in your code?
    o and when you change fontHours to customFont in the drawText line?
    o are you sure customFont has got a value?
    o :
    o :



    - FR935
    - The code works pretty well in the simulator. Saying this I often see some differences on the real watch
    - If I remove the line with font==1 (or better only return Gfx.FONT_NUMBER_THAI_HOT), the code works on the real watch as well
    - customFont has a value, yes. I firstly had the loadResource line in the onLayout() method (and not in the initialize method) but the getFont() line was in inititalize. This leads to that it also worked on the watch if I change this setting. But as soon as I changed to a widget and back the customFont disappeared. I assume that this happened what Jim mentioned: during a complete unload and load of the watchface the initialize method was called first (before the onLayout() method) and therefore the fontHour was null. But the watch didn't crashed. This was the reason why I moved the loadResource line to initialize which showing this behaviour in real world :-(

    What do you see when you use the app settings editor in Eclipse?
    What type is the setting? Number, boolean, etc


    Jim, the setting type is a number. In fact it's a drop down box which returns a number to my code. If I would guess the loadResource() method doesn't work properly in real world if it is called in the initialize() method. I assume it returns anything but not a pointer to the resource of my custom font. And this is what's my watch let crash. Nevertheless, I never thought that a developer can force the watch in such a state...
  • Jim, the setting type is a number. In fact it's a drop down box which returns a number to my code. If I would guess the loadResource() method doesn't work properly in real world if it is called in the initialize() method. I assume it returns anything but not a pointer to the resource of my custom font. And this is what's my watch let crash. Nevertheless, I never thought that a developer can force the watch in such a state...


    That gets back to the New Developer FAQ, point 10. I often load fonts in initialize, and ALWAYS load settings there (and based on "onSettingsChanged")

    It kind of sounds like you may not have the font loaded when you expect it to be on the watch, and sent the FW into a tizzy. While a CIQ app crashing the watch is quite uncommon these days, it still can happen. You may want to post the err_log.txt from the watch when this happens, as the garmin folks can figure out what it means.
  • Hm , Just an idea, what's going on: I load the resources on initialize and set the pointer to that customFont (as you can see it above). Nevertheless, I load the resource again onLayout (didn't delete it from my first try). Maybe, the pointer doesn't work any more since the resource is unloaded and loaded again causing the pointer to point to nowhere. What do you think? I fear to try that since if I would upload it to the store my user may have troubles)
  • you can upload it as a beta app, so you can test it out yourself, I do that too... (you just need a new manifest id for the "beta" app)

  • During initialize:
    customFont = Ui.loadResource(Rez.Fonts.customFont);
    fontHours = getFont(App.getApp().getProperty("fontHours"));


    The getFont function looks like this:
    function getFont(font) {
    if (font == 1) { return customFont; }
    return Gfx.FONT_NUMBER_THAI_HOT;
    }


    The onUpdate method uses this:
    dc.drawText(80, 120, fontHours, hours, flags);


    I load the resources on initialize and set the pointer to that customFont (as you can see it above).

    That should not be a problem. Ideally you'd set customFont in View.onLayout() as there is really no good reason to load the font until it is about to be used. Your getFont() call should also be moved to onLayout() as well (I'm not sure it makes sense to have the getFont() function at all).

    Nevertheless, I load the resource again onLayout (didn't delete it from my first try).

    You don't need to explicitly manage memory in MonkeyC. Objects are reference counted, so when you assign to a variable a little bit of magic happens. The result is that the second call to loadResource should essentially be a no-op.

    Maybe, the pointer doesn't work any more since the resource is unloaded and loaded again causing the pointer to point to nowhere. What do you think? I fear to try that since if I would upload it to the store my user may have troubles)

    No. Provided there is no bug in the reference counting, this cannot happen.
  • return Gfx.FONT_NUMBER_THAI_HOT;
    Is this legal on EU/US devices? Thai fonts are not standard, as I know.
  • This is available on all devices. Check the uxguide in the root of the sdk folder.
  • Nevertheless, I load the resource again onLayout (didn't delete it from my first try). Maybe, the pointer doesn't work any more since the resource is unloaded and loaded again causing the pointer to point to nowhere.


    Not sure about the memory management - but travis has already given answers here - but the worst case should be that you fill the memory with font resources and the font handle is linked to just the latest copy.
    Anyhow, why not just removing the multiple loading part? And then, what happens?!

    Still would do some output for checking in the simulator, first each time after you have loaded a font resource: Sys.println("new font: "+customFont);
    ...and before you do a drawtext: Sys.println("draw font: "+customFont);

    Are you declaring customFont multiple times? (you can easily check that by using my tool Bird's IQ)