Skip navigation

Flex 3 runtime loading with RSLs and Modules

Before I start I know a lot of people just want to see demos so here are links to the two demos I have. They can also be found later on in this post.

DynamicFactory
RSLs on demand

I wanted to load code into my Flex application during runtime instead of compiling it into my app. I was not quite sure how to go about doing this and many google searches revealed nothing. At this point I was not even sure it was possible but after much research and playing around I came up with what I think is a pretty decent way of doing this and decided that I should share it with everyone. I created a couple sample applications to show how this can work and enabled the source so you can see exactly what is going on. There are two examples one that makes use of Modules (my personal choice) and one that uses RSLs. Read more about both below.

Why not just compile everything into your app?

Recently I was working on a project that was basically made up of a number of smaller components. Users would be able to select and add components to it during runtime. Also new components would be released periodically and I did not want to have to rebuild the application every time a new component was released. The app would be able to get information about all of the components from a database so the application would know that these new components existed. I just needed to come up with a good way to load them. I considered several options such as compiling each component into its own swf. I could then load each swf as I needed it. This method seemed kind of dirty plus I wanted a way to load actual classes and be able to instantiate them my self. I decided to figure out a way that I could load code into the application during run time similar to how a dll can be loaded during a programs execution. This would give me a couple of benefits:

  • The ability to load and use classes not built into the main application at compile time
  • Separation of code into different swfs
  • Make code changes with out recompiling the entire application
  • Faster application load times
  • Save bandwidth by loading only the code you need when you need it
  • Provides an easy way to add extend and add to an application

Runtime-shared Libraries

Read about using RSL’s

Now you might be thinking “Haven’t you ever heard of runtime-shared libraries?” Indeed I have heard of runtime-shared libraries and used them numerous times. In fact my first attempt to this runtime loading was with RSLs and it worked alright but it was not quite what i wanted. See my example below.

Usually runtime-shared libraries are used to tell Flash Player to cache certain libraries so they do not need to be loaded everytime your app is loaded: They are also used so that multiple apps can share common code. This works by telling Flex which libraries you want to load as runtime-shared libraries. Then your application gets compiled with out them and you compile them as runtime-shared libraries with mxmlc. The libraries are then loaded the first time you run the app and cached by the Flash Player (if they are signed). The next time the application loads it will not need to reload those libraries as they are cached. This make the first application load a little slower but subsequent loads can be much faster, especially when you cache the Flex frame work. Even if your RSLs are not signed this still allows you to make code changes once and not have to recompile all of your apps just the one RSL that changed.

That being said it is possible to load runtime-shared libraries on demand during runtime, not just at the very beginning. The classes they contain can then be used just as if they where at compiled into the application.

This is the first method I tried to use but soon found it difficult to compile the components because of different dependencies for each one. I put together a couple prototypes using RSLs and ran into some problems: Most of the time it was missing dependences. For example one of the components was a Button but I had problems getting the halo.skins package into the RSL and thus caused runtime errors. I imagine most of these were caused by the way I was building the RSLs but I decided to see if there was an easier way.

Loading RSLs on the fly example (View Source Enabled)

RSLs on demand

To load an RSL at runtime you just have to use a Loader with a LoaderContext to load the RSL into your main applications ApplicationDomain. I have enabled view source on this example also.

Modules and the ModuleManager

Read about using Modules

After doing a little more searching I remembered a little thing called Module. Modules are specifically meant to be loaded at runtime and they are super easy to build. They also can be optimized similarly to how you can choose what packages you build into an RSLs. After reading the documentation I decided that Modules might the way to go.

Most of the time Modules are used to load complex forms or other large components at runtime to help cut down applications initial load. Using the mxml ModuleLoader you are able to load and unload these Modules and then use them just like any other UIComponent. You can also use the ModuleManager class to load a Module if you require a little more control. The ModuleManager returns an IModuleInfo which can be used to create and instance of the Module.

Close but not quite what I was after

This was great but I wanted to be able to load any type of code at runtime not just a Module, which is a UIComponent. I wanted to be able to load and use class references so I could do instantiation my self. I had an idea that would still use Modules but the Modules that I loaded would really act as a factory. This factory could then return what ever it was I really wanted. This would allow me to load anything: It could be a UIComponent, a Class, or any other type of object, not just a Module.

What I came up with

I ended up building a class called DynamicFactory which has a public method createFromModule. This method loads a module that implements IFactoryModule and then returns what ever it was that you really wanted. This method takes 2 parameters type (the type to create) and moduleUrl (the location of the Module to use). This setup is very flexible because I can return both instances and classes from the Module. Also having multiple components in one Module gives some performance increases over having a separate Module for each component. This is because once a Module is loaded subsequent creations from it do not have to reload the Module.

DynamicFactory example (View Source Enabled)

DynamicFactory

In this example the Module urls and the types that they can create are hard coded into the application. In a real situation these values would come from a database or some other source. This would allow the application to use new components as they are created. Also note that once a module is loaded creating another component from the same module does not cause the module to be loaded again. The ModuleManager is smart enough to know which Modules are loaded.

Final Thoughts

I would guess that most of the time, most people could satisfy their needs using just the Module and ModuleBase Classes. I had some specific needs and that is why I created the DynamicFactory Class but I would first recommend trying to use the stuff that Flex already provides.

Advertisements

36 Comments

  1. One possible way to do this is to hot compile your code using a tool like BlazeDS. There are speed considerations, but you basically can do.

    SWF Wrapper modifies MXML
    Post MXML to server
    Hot compile builds MXML into SWF
    SWF Wrapper loads SWF with SWFLoader

  2. In my opinion, Module and RSL’s have different usage scenario. You will use Module’s when you want have a Shell/Module kind of architecture, for e.g. if you are building an Enterprise Application, it is large enough and you cannot accomodate whole thing in a single swf, there you will use Module. Now, you will use RSL’s where you have some common code/components to be used by a number of modules and you want to keep them separate. RSL’s get loaded before your main Application loads. You have mentioned that “it is possible to load runtime-shared libraries on demand during runtime” well, could you please tell me how to do that. I have searched it for a long time but only answer which I found is RSL’s are loaded before your application is loaded. So, I am not sure how you did this and about caching I think Flash Player caches only signed RSL’s.

    • Yes you are correct Flash Player will only cache signed RSL’s. I also liked your explanation of when to use Modules and when to use RSL’s. I was comparing using Modules and RSL’s while trying to load things at runtime and because Modules are meant to be loaded at runtime (not before the application is loaded) they seemed like a better fit.

      Later today I will find my RSL runtime code and post it so you can see how I did it.

    • Have a look at this app. It has view source enabled so you can see whats going on. Sorry it is a bit messy, I threw it together pretty quickly. Basically you use a Loader with a LoaderContext to load the RSL into your main application. Then using the ApplicationDomain class we can get our classes by doing something like this:
      var myClass:Class = ApplicationDomain.currentDomain.getDefinition(“my.library.WhatEventIWant”) as Class;

      Here is a link http://www.chill-mode.com/flex_examples/rsl_loading/main.html

      I hope this helps you.

  3. Hi,

    I am a newbie in flex. I would like to know whether there is anyway to use an mxml component as a display object to be used in the coverflow animation?

    I am really looking forward to do the apple coverflow or deck animation in one of my projects.
    Ive seen its possible to do it using sprite or a display object. But i want to use an mxml component, preferably a canvas in my case. I know its possible, but i am sort of confused right now due to the several other methods that i have already resorted to.

    I know its hard for you to understand what i mean. Because I cannot clearly explain it. Just think of a coverflow design wherein you are not using a display image or sprite object to be used as the image, instead you are using an mxml file to be loaded as it is.

  4. Bullseye ,,,,

    Thanx very much…I wanted to do just that….

    Thankyou again…
    I would like to add you so that I can pester you with my silly flex doubts…if you dont mind 🙂

    Regards and Thanks…
    My mail id:ariesaru2002@gmail.com

  5. Hi,

    I tried out the dougmccune component classes. They fit well except for one small issue which i cant figure out…

    its:the definition of base class moviematerial was not found…

    error 1017.

  6. Where is the “TestLib.swf” or
    “TestLib.mxml” which gets loaded in the main.swf of the example “RSL loading” mentioned above?

  7. Hi Bob,

    First of all thanks for sharing a wonderful piece of work.
    Now coming back to the problem i am facing, I was trying to use this class to load a component at run time instead of module. But till now no success, so I thought I should ask you once. You have mentioned the same in your blog above, so I understand this is possible. Can you please show me the way to achieve this. Thanks in advance for your help. I was getting the following error when I was loading the component.
    “SWF is not a loadable module”.

    Please suggest. Thanks.

    • The code above shows how you can use load a module and pull components out of it. This sounds like what you are trying to do, if I’m understanding you correctly. Alternatively you can you the RSL example if you want to avoid modules. Be aware that I ran in to some issues when using RSL’s. You have to make sure you build them correctly or else they might be missing code that they need.

      As far as your error:

      The “SWF is not a loadable module” error can be caused by several things. The most common one I know is security sandbox errors. If the module you want to load is not in your security domain the flash player will not load the swf and this error can be the result. Are you running a local swf trying to access the web, or a web swf trying to access your local drive? Either of these conditions would cause a sandbox error.

      This error can also be caused if you did not build the swf as a module. A module must extend from ModuleBase or Module and be set in your project to build.

      Let me know if that helped.

      • Thanks Bob. This answer saved me too. I also had to add this attribute to my module implementation to get rid of the “SWF not loadable” error:

        implements=”roidrage.modules.IFactoryModule”

  8. Hi Bob,

    Thanks for your immediate response and this wonderful explanation…anyways..I think I mistook the blog..I understood it this way that we can load a component dynamically without putting it into a module…but no worries now I have understood it well..Thanks for this stuff..Will get back to you if I have further questions.

    You have been a great help. 🙂

    Take Care.

  9. How do you put multiple components into one Module? As far as I know, you set your modules in Flex by choosing a .mxml or .as file, how can you have more than one component in a single .as file? This is exactly what I need for the project I’m working on now and still couldn’t find a solution..

    • That is exactly what the example above is doing.

      If you look at the code in this example http://www.chill-mode.com/flex_examples/runtime_loading/ModuleLoading.html (view source is enabled) you will see that I do have multiple components in one Module. Basically I have it set up so that I can load some Module and pull which ever component I want out of that Module. In the code above a Module can have one or more components. Basically I am treating the Module as a factory from which I can create some component.

        • Dodo
        • Posted July 16, 2009 at 2:36 pm
        • Permalink

        Thanks, that’s a great example.

        But to make it clear, you are using RSLs inside of modules, right? The TransformableCanvasWithImage in FactoryModuleOne is not implemented in the project, so I guess it comes from the library. So, to put multiple custom components into a module, I must create the components in a library project and compile that project to create the RSL, reference them from the module, then load the module dynamically like you did in your example, right?

        Btw I’m very new to flex, sorry if I’m asking something very obvious 🙂

  10. The Modules are NOT using RSLs. I have two separate examples above, one showing how to load dynamically with RSLs, and one showing how to do it with Modules.

    With Modules you simply need to import the classes into your Module as you would normally.

    import what.ever.you.Want

    Doing this compiles all of that code into your Module. At run time then, when you load the Module with DynamicFactory it calls the create() method on the Module and the Module returns the type of component that you wanted.

    Again all of the code is compiled into the Module there is no need to use RSLs with the Modules.

    The reason you do no see the code for TransformableCanvasWithImage is because I did not enable that code in the source. That is going to be a separate post in a couple days.

    • Ok, thanks again for the clarification..

      My problem was about using flex and as, I thought whenever I write a custom component, it’s automatically linked to the main swf, since I see those custom components in the components tab in flex builder. But obviously they are linked when you import them in .as code, as you do in your modules, thanks again..

  11. Hi,

    I’m kinda new to flex. I was seaching through the web for loading components dynamically and first on the list was your post. I did understand somewhat about modules.

    Then i saw a post @ http://livedocs.adobe.com/flex/3/html/help.html?content=containers_intro_6.html in which it used ActionScript to create the components using the addChild methods.

    So could you please tell me which one is the better off the two. I’m sure you might have considered this too.

    Thanks.

    • Loading components at runtime and creating components at runtime are two separate things. Generally if you load a component at runtime you will also be creating an instance of it at runtime, so there is really not a question of which is better.

      Think of dynamically loading components as dynamically adding/importing code to your app at runtime instead of having to recompile your application.

      The real question is whether or not you need to be dynamically loading components at runtime, as this adds a lot of complexity and may be overkill for a small app.

  12. Great example! I downloaded the source and tried to recompile it to mess around and see how it works and I am getting the following errors:

    Module src/FactoryModuleTwo.mxml is set to be optimized for an application that does not exist: src/OptimizeFor.mxml.

    and it can’t find RoidRage.swc

    Can you let me know where these two files are or where I can find them? Thanks again!

    • Hey,

      It sounds like I had my modules set to be optimized by the compiler to an application that I did not include in the src, sorry about that I have not used the view source option very much and did not have my project set up very well for it.

      If you are using flex builder you can go into the project settings and remove the optimization or set the modules to optimize with ModuleLoading.mxml. You can also open the .actionScriptProperties and edit it to match ModuleLoading.mxml or any other mxml file you have in the project and that should remove that error.

      As far as the RoidRage.swc not being able to load if you go into the project properties you can remove that resource from the project and also remove the second case from FactoryModuleOne.xml case “TransformableCanvasWithImage”:

      Doing those two things should enable you to compile I just tried it and got it to work. I uploaded a new zip with these changes, try this one and you should have better luck.

      http://www.chill-mode.com/flex_examples/runtime_loading/srcview/ModuleLoading_fixed.zip

  13. This was exactly what I was looking for. Thanks!

  14. I am a newbie to Adobe Flex & Actionscript.

    I need your help in one of my requirements. Here it is

    I have a main mxml file. Now, inside this file, I have a group in which I wanted to load dynamically a login screen(with username, password field & a submit button) on initial startup. Once I submit with the login details, it should load a different mxml component in the same group as that of my previous login screen.
    I am trying to preserve my header & footer information like in any other language and I dont want to add the same header footer information everytime.

    I choose a group in main mxml file which I wanted to load data based on different operations. Is this achievable?

    I tried to invoke initialize function inside group but stuck with adding logic for my requirement.

    Please provide your valuable inputs.
    I feel your post suffice me but unable to get it worked.

    Thx

  15. ok, I got it working.
    Your post gave me confidence that I could achieve :).

    Thx

    • I am glad to hear you got it working.

      I may have misunderstood what you are trying to do, but it sounds like this might be a bit overkill. If I understand correctly your app already knows all the components it will just it is just a matter of swapping them around at runtime. If so compiling them into the app is probably fine at first or try just using normal modules. I say this because if you are new to flex modules and runtime loading like I am talking about here can introduce hard to find bugs if you are not careful.

      Anyways if you have anymore questions about this or anything else feel free to ask.

  16. Hi. thank you for this. I haven’t looked through everything but seems to be what I need.

    I’m building an AIR app for a client that makes use of some very heavy swfs that have embedded video, which I need to control from the main application. It was choking the compiler, so I broke it into separate Flash files. But just loading the SWFs using SWFLoader gives you no control over methods and timeline navigation. I want to be able to load the swf and access custom.

    This seems promising.

  17. Hi,

    Thanks for this great bit of code. It is the best example of module loading I could find. I am really new to AS 3 but know java and a few other languages. What is not clear to me is how to extend the code so that I can write a module to load with something life a form or a video. I guess the question is how do I replace “return new Panel();” with something more complex. Any help would be greatly appreciated.

    -Nick

    • Thanks for the feed back its nice to know this is helping someone.

      To answer your question directly take a look at the code in FactoryModuleOne.mxml and look at the TransformableCanvasWithImage case. This shows that you can build up anything you want and return it back. There is no restriction to what you can return, for the sake of the demo I kept things pretty simply.

      Like I said in the article, the DynamicFactory Class is probably over kill in a lot of cases. You should first try using standard Modules and ModuleLoaders as they are much simpler to use. This would certainly be the case if all you want to load in is a form or a video player.

  18. Thank you very much for saving me a lot of time! This article and factory are exactly what I was looking for =)

  19. An impressive share! I’ve just forwarded this onto a colleague who had been doing a little homework on this. And he actually bought me lunch because I stumbled upon it for him… lol. So let me reword this…. Thank YOU for the meal!! But yeah, thanks for spending the time to talk about this matter here on your blog.

    • Awesome. I love to hear that these posts are helping people, better yet feeding people!

  20. Thank you for this. I just started a project in which I’m having exactly the same requirements, and this provided the perfect solution. Small, simple, fast, …elegant.


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

%d bloggers like this: