Flex App Hung?

I finally decided to post about the most common reason your Flex app hangs and stops responding: invalidation/validation loops.

Flex has a LayoutManager that has 3 phases for processing the properties, size and visuals for each component. When a property is changed on a component, the component is supposed to notify that LayoutManager that a property has changed, and potentially that the size of the component has changed as a result, and potentially that the component needs to be redrawn. The component does so by calling one or more of invalidateProperties(), invalidateSize() and invalidateDisplayList(). The LayoutManager builds a queue of components that need validation, but generally does not validate the components right away. This allows related properties like width and height, or fontSIze and fontFamily to be changed but only result in one update of the display list.

Later, the LayoutManager will go through its queues and call validateProperties() on all components in the queue that had called invalidateProperties() (which could cause other components to call invalidateProperties() and end up in the queue), then when all component’s properties have been validated, it will call validateSize() on all components that have called invalidateSize() and finally, call validateDisplayList() on all components that have called invalidateDisplayList(). Then before exiting, the LayoutManager will check again for things in the queues that might have been invalidated during validation. If it didn’t do that, sometimes your display list would end up in an incomplete state at render time.

A call to validateProperties results in a call to the component’s commitProperties() method. A call to validateSize() results in a call to measure() unless the width and height of the component are set, and a call to validateDisplayList() results in a call to updateDisplayList().

If you think about it, you can see that if, in the measure() or updateDisplayList() calls you end up accidentally calling invalidateProperties(), invalidateSize() or invalidateDisplayList() on the wrong components, those components will keep ending up in the queue and the LayoutManager will never finish.

This usually happens when the measurements for a component are not “stable”. If the component reports measurements based on its current size, then a intentional increase in size might cause it to report a bigger size which would cause it to be given a larger size and thus report an even bigger size and so on.

To find out if you are in such a loop, set a breakpoint on LayoutManager doPhasedInstantiation(). In a good app, there will be a bunch of calls to doPhasedInstantiation(), but once everything is validated, there won’t be any more calls until the screen needs updating due to user interaction or data coming in over the network and being displayed.

If doPhasedInstantation() is being called over and over and over again, the next step is to set a breakpoint in invalidateProperties(), invalidateSize(), and invalidateDisplayList() and see if the same set of components keeps getting invalidated. Somewhere in that set is the culprit. It is pain staking work, unfortunately.

If you know how to monkey patch, you can uncomment the trace statements in LayoutManager and get a dump of its activity and look for repeats.

But even then, it comes down to debugging the logic of that component or set of components and understand why they keep invalidating themselves.

HTH,
-Alex

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s