Edge 1000 FW 14.70 - onUpdate() being called more on actual device than simulator

I was doing some updates to my weather radar app, since I was doing some updates, I had some debugging lines to print the URL and parameters for the radar image. After getting things working as expected in the simulator, I did a test build with the logging code still enabled and installed on both my FR230 and my Edge1000 with an empty text file in the garmin\log directory. Things worked as expected on the FR230, but in the log from the Edge1000 showed two URL entries for for each image retrieval request. After a little more troubleshooting I added a flag which gets set to true right before doing the makeImageRequest and set back to false in the ReceiveImage method to handle the image receipt. I also put a println at the start of the onUpdate() method to print the status of the flag and added a check that would only execute the generate URL and run makeImageRequest if the flag was false. After running the revised code in the simulator I got the following output (API keys hidden)

false
false
api.wunderground.com/.../image.gif
{height=>360, newmaps=>1, width=>240, centerlat=>38.895995, centerlon=>-94.760896, radius=>16}
IMAGE OK
false
Aeris Weather Selected
false
false
maps.aerisapi.com/.../current.png64
null
IMAGE OK
false
Weather Underground Selected
false
false
api.wunderground.com/.../image.gif
{height=>360, newmaps=>1, width=>240, centerlat=>38.898025, centerlon=>-94.761416, radius=>16}
IMAGE OK
false
Complete


Then after doing a build and uploading as a beta version and installing on the Edge1000, I get the following output.

false
false
false
api.wunderground.com/.../image.gif
{height=>360, newmaps=>1, width=>240, centerlat=>30.037376, centerlon=>-95.614880, radius=>16}
true
IMAGE OK
false
false
false
Aeris Weather Selected
false
maps.aerisapi.com/.../current.png64
null
true
IMAGE OK
false
false
false
Weather Underground Selected
false
api.wunderground.com/.../image.gif
{height=>360, newmaps=>1, width=>240, centerlat=>30.037448, centerlon=>-95.614870, radius=>16}
true
IMAGE OK
false
false
false


Because on the Edge1000 I am seeing the true between the printout of the URL and the IMAGE OK, I can tell that the onUpdate() is getting called an additional time on the actual device when compared to the simulator.

A little more background, I am running for my development environment Eclipse Oxygen2 release 4.7.2 with the CIQ SDK 2.4.3 installed.
My Edge1000 is running 14.70

I will send an email with the code sample.
  • Here is some simplified code which can reproduce the issue. Note in the URL you need to replace the API_KEY with a valid weather underground developer key. This code retrieve an image and refresh every 30 seconds with logging for steps along the execution.

    using Toybox.WatchUi as Ui;
    using Toybox.Graphics as Gfx;
    using Toybox.System;
    using Toybox.Lang;
    using Toybox.Time;
    using Toybox.Time.Gregorian;
    using Toybox.Timer;
    using Toybox.Communications as Comm;
    using Toybox.Application as App;

    class imagedlView extends Ui.View {

    var TimerMin = .5;
    var mySettings = System.getDeviceSettings();
    var bitmap=null;
    var imgurl = null;
    var imgparam = null;

    function initialize() {
    View.initialize();
    }

    // Load your resources here
    function onLayout(dc) {
    var resetTimer = new Timer.Timer();
    resetTimer.start(method(:RefreshReset), TimerMin*60000.toNumber(), true);
    }

    // Called when this View is brought to the foreground. Restore
    // the state of this View and prepare it to be shown. This includes
    // loading resources into memory.
    function onShow() {
    }

    // Update the view
    function onUpdate(dc) {
    // Call the parent onUpdate function to redraw the layout
    View.onUpdate(dc);
    System.println("onUpdate start");
    mySettings = System.getDeviceSettings();
    if (mySettings.phoneConnected) {
    if(bitmap==null) {
    imgurl="api.wunderground.com/.../image.gif";
    imgparam = {
    "centerlat"=>38.855166,
    "centerlon"=>-94.799379,
    "radius"=>16,
    "width"=>240,
    "height"=>360,
    "newmaps"=>1
    };
    System.println(imgurl);
    Comm.makeImageRequest(imgurl, imgparam, null, method(:onReceiveImage));
    } else {
    dc.clear();
    dc.drawBitmap(0,0,bitmap);
    }
    }


    }

    // Called when this View is removed from the screen. Save the
    // state of this View here. This includes freeing resources from
    // memory.
    function onHide() {
    }

    function onReceiveImage(responseCode, data) {
    if(responseCode==200) {
    if(data instanceof Ui.BitmapResource) {
    System.println("IMAGE OK");
    bitmap=data;
    Ui.requestUpdate();
    }
    } else {
    bitmap=null;
    System.println("imgstatus="+responseCode);
    Ui.requestUpdate();
    }
    }

    function RefreshReset() {
    bitmap=null; // clear image
    System.println("image reset");
    Ui.requestUpdate();
    }

    }



    This is the output from the simulator when run for 2 refreshes.:
    onUpdate start
    api.wunderground.com/.../image.gif
    IMAGE OK
    onUpdate start
    image reset
    onUpdate start
    api.wunderground.com/.../image.gif
    IMAGE OK
    onUpdate start
    image reset
    onUpdate start
    api.wunderground.com/.../image.gif
    IMAGE OK
    onUpdate start
    Complete


    This is the same code built for the Edge1000 and run for 2 refreshes.
    onUpdate start
    api.wunderground.com/.../image.gif
    onUpdate start
    api.wunderground.com/.../image.gif
    onUpdate start
    api.wunderground.com/.../image.gif
    onUpdate start
    api.wunderground.com/.../image.gif
    IMAGE OK
    onUpdate start
    IMAGE OK
    onUpdate start
    IMAGE OK
    onUpdate start
    IMAGE OK
    onUpdate start
    image reset
    onUpdate start
    api.wunderground.com/.../image.gif
    IMAGE OK
    onUpdate start
    image reset
    onUpdate start
    api.wunderground.com/.../image.gif
    IMAGE OK
    onUpdate start
    onUpdate start
    onUpdate start


    Definitely, when running the code on the device, it is much more out of order execution and more times onUpdate gets called.

    FYI, I am also seeing device having problems going into mass storage mode after updating to 14.70, but that is a topic for another forum.
  • Former Member
    Former Member
    The onUpdate() function is the rendering callback for your application. It is not recommended to handle logic other than rendering here. In general, this method is only called when your application calls WatchUi.requestUpdate(), but it is possible that it may be triggered at any time due to system events such as a native UI notification obscuring the screen.

    I recommend making this image request from your timer callback instead of the onUpdate() method. If you wish to continue making this request from onUpdate(), you should block the entry into that block as soon as the request is made as opposed to when the response is received to prevent repeating the request as seen here.

    We will look into the extra onUpdate calls on the Edge 1000.
  • Brian,

    Thanks for the feedback on how to better handle the image request. I will take that under advisement and make some adjustments to improve the handling. It is always good to improve the code as we learn.

    I will be interested to hear what you find on the Edge. I was surprised to see the edge logging differently than the simulator. When I tested my app on the FR230, the log did look the same as the simulator.


  • Brian,

    I have implemented the recommended improvements by moving the image retrieval into a function which is called by the reset function or onLayout. Now onUpdate only renders a message getting image or the image if it is available.

    I am still seeing more executions of the onUpdate on the actual Edge1000 than I see in the simulator, but the good news is my app is able to handle it much better now. Thanks for the recommendation.