Strange crashes on Edge datafields lately

After many weeks of no ERA reports, I have now received several messages for data fields for 2 weeks - only on Edge 1040 and 1050 devices. All of them refer to the initial loading - or rather “not loading” of variables. I know that with data fields “onCompute” and “onUpdate” do not necessarily work synchronously - or rather - in a continuous sequence. But since the last software updates of both devices, there are suddenly problems.
-With System.getDeviceSettings() screenHeight is only successfully queried in the second run. However, since this variable is already required in the first run of onUpdate, this leads to problems there.
-The same with the loading of consumer fonts. This leads to crashes with dc.drawText because the font is only loaded in the second second.
None of this has been a problem so far. The code has not changed.
Now I have to come up with security routines to avoid the crashes.
Has anyone else noticed anything like this?

(the consumer font crashes do occure only on few devices. They are not reproducable on my devices… and do not happen on the simulator)

(on my devices I was able to reproduce the „too late reading“ of screenHeight. It also does not happen on the simulator)

  • With System.getDeviceSettings() screenHeight is only successfully queried in the second run

    Could you clarify what you mean by "successfully queried"? Does System.getDeviceSettings() return null or a valid object? If a valid object is returned, what's the value of DeviceSettings.screenHeight? Null, 0, or some other incorrect value?

    The same with the loading of consumer fonts. This leads to crashes with dc.drawText because the font is only loaded in the second second.

    So I assume the first call to loadResource returns null?

    Can you provide code snippets? Are you loading resources in onUpdate() or onLayout()? If you're loading them in onLayout(), maybe the problem is actually with an assumption that onLayout() is always called before the first onUpdate(). (Yes, I know that docs literally say this.)

    Is it possible for you to load your resources (and do other setup) in View.initialize() or AppBase.initialize()? Either of those functions should be guaranteed to be called before the first onUpdate().

    (on my devices I was able to reproduce the „too late reading“ of screenHeight. It also does not happen on the simulator)

    Can you provide a small working (or should I say non-working) example of this?

  • Thanks for your respond!

    Could you clarify what you mean by "successfully queried"?

    Find below a code snippet where I try to get screenHeight at the end of initialize() and at the beginning of onCompute().

    ( I'm sorry - but I cannot insert code - forum software says: "You're blocked" - I insert the coda as text:

       
            mySettings = System.getDeviceSettings();
            scrWidth = mySettings.screenWidth;
            scrHeight = mySettings.screenHeight;
            if ( scrWidth == 480 ) {
                //myFont = WatchUi.loadResource(Rez.Fonts.id_font_myFont5);
                //myArrows = WatchUi.loadResource(Rez.Fonts.id_font_myArrows5);
            }

        }       // Ende Initialite()


        // The given info object contains all the current workout information.
        // Calculate a value and save it locally in this method.
        // Note that compute() and onUpdate() are asynchronous, and there is no
        // guarantee that compute() will be called before onUpdate().

        //############################################################################
        function compute(info as Activity.Info) as Void {
           
            mySettings = System.getDeviceSettings();
            distEinheit = mySettings.distanceUnits;    // metric = 0  / statute = 1
            hoeEinheit = mySettings.elevationUnits;    // metric = 0  / statute = 1
            tempEinheit = mySettings.temperatureUnits;  // metric = 0  / statute = 1
            timeEinheit = mySettings.is24Hour;          // true...24h / false ...12h        // ist oben initialisiert!
            scrWidth = mySettings.screenWidth;
            scrHeight = mySettings.screenHeight;
           
    In the first second I get no value for screenHeight.
    System.getDeviceSettings() returns null.
    See picture below:
    The left 2 pictures show the load process for the first 2 seconds.
    The right picture shows what's going on. (fieldHeight - from onUpdate() - is not always shown in first second either)
    (picture Upload does not work either - f*** forum :-(  )
  • The first line on right picture is the result of System.getDeviceSettings() in first second

    The 2 variables on the right picture are the first second of:
    var scrHeight = 0;    ( filled from getDeviceSettings)
    var fieldHeight = 0;  ( filled in onUpdate()  )

    I cannot submit a small working datafield, showing this problem. When I create a short datafield, the problem does not occur.

    And doing many tests for making a video it turned out, that this problem is also not 100% reproducable. Somitimes it works in the first second!

  • Regarding consumer fonts:

    Are you loading resources in onUpdate() or onLayout()?

    As long as possible I load consumer fonts in initialize().

    But for datafields for more EDGE devices and more field layout options I often can load a consumer font only in onUpdate() because I need to know the fieldWidth and/or the fieldHeight.

    For loading only one time, I use If myFont == null as condition.

    But this sometimes doesn't work either for the first second...

    As I stated in my OP, this problem only occurs with the Edge 1040 and 1050 devices, and it rarely happens.

      

  • Can you print the values? Is it possible you always get a value, it's just not what you think (480)?

  • On the simulator all works perfectly.
    On the real device I get System.getDeviceSettings() = null at the first reading. Only the second reading delivers the object.

  • And the 1st time is from the constructor of the app class?

  • Sorry for the post-as-screenshot, but the forum hates me

  • I agree. I think you expect it to be 480, but it might be something else. In some edge devices there are virtual buttons, that decreases the height, maybe something like that is also done to the width.

  • Unfortunately, the thread has become rather confusing. And stupidly, I have described two different issues. In addition, I copied various blocks in the code snippets as a test and created additional ones - in a word: it has become too confusing.

    Let's just describe the one case that happened on my device and was reproducable (not on every start).
    It is the issue of which I have posted pictures.

    This is the simplified code, I had at the beginning of research:

        function onUpdate(dc as Dc) as Void {
    
            var mySettings = System.getDeviceSettings();
            scrWidth = mySettings.screenWidth;
            scrHeight = mySettings.screenHeight;
            fieldWidth = dc.getWidth();
            fieldHeight = dc.getHeight();
            
            var hi = scrHeight / 4;
    
            for (var i = 0; i < 4; i++) {
                // do all the drawing stuff using i*hi as base of y value
            }    
    
        }            

    On the first run of onUpdate() the value hi (which should be 1/4 of screenHeight) stays 0, because scrHeight = mySettings.screenHeight stays 0.

    Only the second run fills real values into the variables.
    This is the base of my pictures in an above post.

    I then I moved the scrHeight definition ( mySettings ) to initialize(), but this did not change the fact, that the value hi ( = 1/4 of screenHeight) is filled with the correct value before scond 2.
    To add the scrHeight definition ( mySettings ) to onCompute() was also not successful.

    This case has nothing to do with ERA crashes. It leads to no crash. I have noticed a strange picture of the datafield in second 1 on my device, so I started to research.