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 

  • I added the devices to the initial report  – great you are on it.

    There were many more devices in the ERA log, but I already deployed a hotfix so the log got cleared and now I only have a report from a watch face with quite a small user-base. From what I can recall, there were also devices like FR965 or Epixes. A huge list of devices and thousands of reports. 

    The user who reported it to me (including a screenshot from his FR265) claimed, it was happening occasionally, not always, but after we started to investigate, it happened within hours. He did not have AOD on. I don't know about others, because I can't contact them. 

  • > I don't call the onExitSleep

    I didn't say or even imply that you were calling it yourself. As we all should understand, the onEnterSleep/onExitSleep methods are hooks for the system to notify the application that it is changing states. The system calls these functions, and those calls should only happen at specific points in the watch face life cycle.


     - The problem is that sometimes system doesn't call onLayout, onShow etc.... 

    If you are seeing app life cycle errors (onShow called before onLayout, onLayout not getting called, onExitSleep called before onEnterSleep, any member function called before initialize), those issues should be reported. We need information on the device that produced this behavior, the firmware version, and ideally a sample app with debug output that demonstrates the problem actually occurred. A simple test app with System.println() in each life cycle should be sufficient to demonstrate the problem in most cases, and we can create that ourselves, but sometimes that is not enough.

    Maybe I'm not spending enough time on the app development side, but I don't think I've seen this happen in a *long* time. It would be extremely difficult for it to happen as the app work area keeps a series of flags to indicate the app state. If the device tries to call a function before a prerequisite has been called, the prerequisite will be called automatically. i.e., if the system wants to call onUpdate, but onLayout and onShow have not been called, it will call onLayout, set the bit indicating layout has been completed, and will then call onShow and set the bit indicating the view is now visible, then will call onUpdate. Similarly, if the system wants to call onHide and the flag is not set to indicate the view is visible, View.onHide will not be called.

    I'm not saying it isn't possible for something like this to happen, but we have a system in place where it should be nearly impossible. As I said above, if you are seeing cases where this is happening, we need bug reports; ideally with test apps and reproduction steps. If that is not possible, then at the very least we need to see the data that led you to your conclusion.

     - Problem is that sometime system calls onExitSleep:
    > - without the previous onEnterSleep
    > - only after initialise

    No class member function should ever be called before initialize, so I'm not sure what you expect with respect to the second bullet here. You simply cannot safely call any function on a class instance before you have a class instance to call it on.

    As for the first item, this should not be possible. We have a flag indicating the current "power mode" of the application, and we don't allow calling onExitSleep or onEnterSleep on the app if it is already in that power mode.. i.e., app is initially in high power mode and attempts to trigger calls to onExitSleep have no effect, but calls to trigger onEnterSleep do.

    Again, if you have a device details, a test app, reproduction steps, or debug data to support this, I'd love to see it.

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

    Yes

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

    Yes-ish. Technically the system was written originally expecting that resources would be loaded in onShow and unloaded in onHide. You don't have to do it that way. If you are using a device that has a resource pool and you aren't locking resources in memory, you don't need to unload as that should happen automatically as I described previously.

    That's exactly what happens!

    I think you are misreading the data. I'm almost certain if you print the value of fontSmall just before the exception occurs, you'd see that it is non-null. As I tried to describe, fontSmall is a FontReference on current devices, and the FontReference has information contained within to locate the cached FontResource data in a shared memory pool. My bet is that there is a bug somewhere in this logic and one of those internal data members are getting nulled unexpectedly.

    We found an issue with bitmaps that is very similar to this about a week ago. I would not be completely surprised if there was a similar issue with fonts. We are looking at it.

     - Your problem is probably because sometimes system doesn't call onLayout().

    Pleas provide details, preferably in a separate thread.

  • I've written SOMETIMES. Your problem is probably because sometimes system doesn't call onLayout().

  • I don't call the onExitSleep  – the OLED device calls it itself without my intervention.

    Re: "You should never see fontSmall get set back to null."

    That's exactly what happens!

    The exception on that line using the font (previously loaded in initialize) is: "UnexpectedTypeException: Expected Number/Resource, given null…"

    Not sure if that exception continues, because there's no way how to reproduce it without the device. It does not show in a simulator. I don't have an OLED device, so I had to let it print to the device display and let my users to report it to me back.

    Contrary what _psx_ reported, my report is that onEnterSleep and onExitSleep are called correctly, but OLED watches often (not always) remove the font used on that line 
    (without my intervention) and it stays removed when the watch itself calls the onExitSleep. Thousands of reports from a variety of OLED watches. 

  • Problem is that sometime system calls onExitSleep:

    -  without the previous onEnterSleep

    - only after initialise