Acknowledged

OLED: font resources seem to be forgotten while sleeping which leads to a crash onExitSleep

It seems that OLED watches now release fonts when sleeping and onExitSleep is called before initialize, so the app crashes when it uses fonts in the onExitSleep to update the layout. 

I get null exception while a resource is expected on this line that is called from onExitSleep.

"UnexpectedTypeException: Expected Number/Resource, given null…"

I got thousands of failure reports on this line from a variety of OLED devices. 

I do not release fonts anywhere in the code and the same line is called via initialize without problems. 

I hotfixed it by catching the exception and calling the initialize instead, but that is a huge wasting of resources and probably a battery. 

I am not aware of any documentation that the Monkey might release any resources on its own and even if it does, I'd expect it would call initialize before onExitSleep. 

Some of devices where the error occurred: 

  • Venu® 3: 8.25
  • vívoactive® 5: 8.27, 4.14
  • Forerunner® 265s: 17.26

EDIT: added an exception text

EDIT2: added devices 

  • Devices should not be calling onEnterSleep or onExitSleep before initialize. It should be pretty easy to prove to yourself that this is (or is not) happening using the good old System.println() debugger to output the name of the function in each of the calls.

    What is the text of the exception that you catch? This is a critical piece of information that you've omitted that will help to diagnose the issue.

    Yes, the system can evict resources that you hold references to from the graphics pool. This happens silently. The next time you need the resource (you render the bitmap, or render text using the font), the system will evict resources from the pool to make room (if necessary) and load your resource behind the scenes automatically. There is a chance that you (or other apps) have resources in the pool that are "locked" and cannot be evicted. Problems will definitely occur if the system needs memory for your resources and the pool cannot be cleaned up to make room. I believe you'd get a system error on older build, and with newer builds you should get a specific exception to indicate this.

    You should never see fontSmall get set back to null. It is possible that there is a bug down in the virtual machine somewhere that causes a reference that is internally maintained by the system is getting set to null, but you are using these things correctly.

    I've had to say this twice in the last week... You should not be calling initialize() directly on any object EXCEPT when initializing a base class from a derived class initialize(). It could easily lead to resource leaks. We should insert a compiler guard to prevent you from doing it in the first place.

    If you find that you need to initialize data in self again, write a separate function that does that work, and call it from initialize() if that is what you need.

  • https://forums.garmin.com/developer/connect-iq/b/news-announcements/posts/a-whole-new-world-of-graphics-with-connect-iq-4

    The graphics pool will dynamically cache, unload and reload your resources behind the scenes based on available memory. All the drawing primitives that accept resource objects also accept references, as well, so your app should not have to be reworked to take advantage of the new system.

    But I suggest to move loading resource in initialise.

  • When? Is it documented when the system can unload graphic resources? 

  • Sometimes system can unload graphic resources in devices with graphic pool. I don't know if it is possible to prevent this.

    But I think yours case is different: onLayout isn't called so setLayoutVars isn't not called and fontSmall is not loaded.

  • That could be a problem as well, but does not explain why the fonts are removed from memory. 

    I consider onLayout a method to be called when a layout recalculation is needed. 

    I consider initialize the method where resources are expected to load. 

    So if Garmin decides to unload resources by its own, without any instructions to do that, I'd expect it will call initialize again. 

    I'd personally guess, that releasing the resources is a bug as well.