WatchUi.requestUpdate() twice ?

Hi,

I thought I understood what requestUpdate do ... But it's seems it's not the case ... As I understood : when I call WatchUi.requestUpdate(), the onUpdate of the current View is called. It is done when the Widget return to the VM.

So, why the result is not the same when I call WatchUi.requestUpdate() twice in a row vs just one ?

Is the changes made in the View are "stacked" ? Then each WatchUi.requestUpdate() "unstack" some ?

Regards.

  • OK, some details about the context of my question.

    In a widget, in the callback function of a makeWebRequest(), I just modify a global var and do a requestUpdate. Here the code :

    function onReceive(responseCode, data, context) {
        ... some code is not important
        resToDisplay = ["OK", Graphics.COLOR_DK_GREEN];
    	WatchUi.requestUpdate();
    }
    

    In the onUpdate() of my View, I simply display the content of resToDisplay.

    But it doesn't display my result even if, I check with a println(), onUpdate is called.

    After many tests, I just put a second WatchUi.requestUpdate() just after the first one. THE ONLY CHANGE. And waouh !, my View is now correctly updated, I see the content of resToDisplay.

    I don't understand this behavior ... Wihtout changing anything between my to call, how it can change what I see !

    Perhaps I don't understand how it works, let me try to explain what I understand :

    • When I call requestUpdate() it's call the onUpdate(), if permit set all I want like globalView.findDrawableById("result").setText("My text I want to display").
    • But it is not really displayed, it will be when I will have finish to execute my code (in other words return to the VM ?
    • When my code is finished to execute, it return to VM, which display all the changes I have done.
  • Do you see the same behavior on the real device and the sim?

  • And can you post your onUpdate() function?

  • I'm actually testing on my device.

    Here is the code of onUpdate() :

    function onUpdate(dc) {
        // Call the parent onUpdate function to redraw the layout
        View.onUpdate(dc);
    
    	var rezDevice = self.findDrawableById("device");
    	var rezAction = self.findDrawableById("action");
    	var rezResult = self.findDrawableById("result");
    
    	// During loading
    	if (actionsLoaded < TOTAL_ACTIONS) {
            //... not executed here
    	} else {
    	// Loading finished
            var tmp_res_ico = null;
    
    if ((device == null) || (action == null)) {        
            // Some code that is not executed
    
    
                // Some code that is not executed
            } else {
            	if (resToDisplay == null) {
            		System.println("I display PressStart gray");
    		       	rezResult.setColor(Graphics.COLOR_DK_GRAY);
    				if (System.getDeviceSettings().isTouchScreen && Application.Properties.getValue("TapLaunch")) {
    		        	rezResult.setText(Rez.Strings.PressStartToLaunchTouch);
    		        } else {
    		        	rezResult.setText(Rez.Strings.PressStartToLaunch);
    		        }
    		    } else {
            		System.println("I display a result");
    		        rezResult.setText(resToDisplay[0]);
    		        rezResult.setColor(resToDisplay[1]);
    		    }
    	   	}
    	}
    }

  • What happens if you move View.onUpdate(dc); to the end of the function?

  • OK, you find what was wrong. I assumed that View.onUpdate(dc) just displayed the "base" layout (the layout I defined in the xml)... I just understand that is more ! It display the layout I tuned...

    I have to change some things, because if I call View.onUpdate(dc) at the end, it erase (more precisely it hide) all dc.fillRectangle() and dc.drawBitmap().

    But it's clear now, thanks a lot (again)

  • What you do is move the fillRectange() and drawBitmap() after the View.onUpdate(), but just those things.  And dc.setColor() calls if needed.

    You're switching from a layout to direct dc calls, and the View.onUpdate clears the screen before it displays the layout.  So what you did with direct dc calls is lost.

  • We don't document how many calls to View.onUpdate() will be made for multiple calls to WatchUi.requestUpdate(). We just say that it requests the top-most view be refreshed.

    I know that the ConnectIQ simulator currently queues one redraw request per call to WatchUi.requestUpdate(), and I'm pretty sure that most current devices collapse multiple redraw requests into one. So there is a difference in behavior, but I'm not comfortable to say with any certainty that all devices will follow this behavior or have in the past.

    It would not be difficult to update the simulator to collapse multiple requests into one, but since both behaviors are technically allowed, I'm not sure it is a good idea to make a fix either way.

  • I know that the ConnectIQ simulator currently queues one redraw request per call to WatchUi.requestUpdate(), and I'm pretty sure that most current devices collapse multiple redraw requests into one. So there is a difference in behavior, but I'm not comfortable to say with any certainty that all devices will follow this behavior or have in the past.

    It would not be difficult to update the simulator to collapse multiple requests into one, but since both behaviors are technically allowed, I'm not sure it is a good idea to make a fix either way.

    Thank you for confirming this!

    I understand the rationale here, but another way of looking at it is the current behavior in the sim allows us to write code that displays impossibly fast animations on a simulated device. Seems a bit misleading.

    What if the API docs were updated to say that the behavior for calling requestUpdate() multiple times is undefined?

    Then the simulator could be changed as you suggested, and by the logic in your comment, it wouldn't be "wrong".

    EDIT: Even though multiple requests are "allowed" (or not expressly prohibited), seems that the intended behavior is undefined, so it may as well be "prohibited" in the API docs.

  • The simple way to handle this in both the sim and all devices is to just have a simple timer that calls requestUpdate as often as needed. 

    As Travis said "but since both behaviors are technically allowed, I'm not sure it is a good idea to make a fix either way."

    And a timer makes it a non issue, where you can control how often the updates occur.