SWFLoader loading multiple apps and using the same Singletons generates a RTE

Today I was working with a baffling bug in the Flex Bug Base. It was titled “SWFLoader loading the same app twice, which contains Button which pops up alert will throw RTE when clicked on the second button” and you can see it here SDK-11910

I did a whole lot of debugging and finally needed help from Nisheet… to get to the bottom of the issue. The issue is as follows…

You have multiple apps loaded into a main app using a SWFLoader. Now each of the apps loaded use one of the singletons used in the framework (in the case of the bug, it was the PopUpManager, as the person was using an Alert in the sub App). When he tries to use the methods of the Singleton (in this case thru the Alert.show() method in each of the sub apps), it works for only the first sub app and all others generate the following RTE (Run Time Error) for the others

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.managers::PopUpManager$/addPopUp()
at mx.controls::Alert$/show()

In his case, each of the sub app had the following code (Sample.mxml)…

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; layout=”absolute”>
<mx:Button label=”Click me” click=”mx.controls.Alert.show(‘Button selected!’);”/>
</mx:Application>

And his main app was as follows (main.mxml)…

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”&gt;
<mx:SWFLoader id=”swfloader” source=”Sample.swf”/>
<mx:SWFLoader id=”swfloader2″ source=”Sample.swf”/>
</mx:Application>

The following execution map resulted in the RTE

  1. The main app starts and loads the sub apps
  2. When the user clicks the button in the first sub app, the SWFLoader asks its parent if it has an instance of the IPopUpManager interface.
  3. Since the main app has not created or cached its IPopUpManager, it replies negative and the sub app goes ahead and creates one for itself and pop’s the Alert
  4. Now when the user clicks the button in the second subapp, it again repeats Step 2 & Step3
  5. But in Step3, it encounters a code in the framework (in PopUpManager.as)
      private static var impl:IPopUpManager = Singleton
      .getInstance(“mx.managers::IPopUpManager”) as IPopUpManager;
  6. This casting using the as operator fails and thus generates the RTE.

The solution for this is to initialize the main app such that it creates and caches its own IPopUpManager interface, so that both sub-Apps can use the same, without any conflict. The altered main.mxml would look like this

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml&#8221; initialize=”initApp()”>
<mx:Script>
<![CDATA[
import mx.managers.IPopUpManager;

private function initApp():void{
IPopUpManager;
}
]]>
</mx:Script>
<mx:SWFLoader id=”swfloader” source=”Sample.swf”/>
<mx:SWFLoader id=”swfloader2″ source=”Sample.swf”/>
</mx:Application>

This solves the issue. Please Note that this same step has to be taken, also when your sub apps share other managers like CursorManager, HistoryManager…etc.

Advertisements

One Response to SWFLoader loading multiple apps and using the same Singletons generates a RTE

  1. kanu says:

    Raghu can you please send me the sample files for this bug.
    I want to see that what kind of bug you faced.
    I have downloaded the SDK source file but nothing shows me the bug you have specified.

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