Skip navigation

Category Archives: Flex Coding

Image caching with Flex 3

As always I will start with my examples because I know most people want to see a demo before reading about it. Both of these examples are identical except for one line of code which flags image caching on or off. I have added stats.as so you can see the memory usage as you load more images. You will notice that when using the example with image caching you can load hundreds of images with little memory impact and it is much faster than the example with out caching. Also if you do not believe stats.as open up your task manager and view the memory usage of your browser to confirm that ImageCache is really working.
View source is enabled so you can see whats going on.

App NOT using cache
App using cache

I have seen several Flex 3 image caching solutions out on the web but most of them seemed to subclass SWFLoader or Image. In my opinion the Image class should know nothing about caching, it should just know about displaying the image. Why add extra functionality to the Image class? Why not have something else manage the caching? So I created ImageCache which is a utility class that handles caching images which can then be used as the source for any Image component.

The reason I like this approach is that it leaves the Image class alone and if you want to cache something you do not need to swap all the Images in your app with some subclass. You only need to change the way you set the Images source property.

I thought the browser cached images?

You may think that you don’t need to cache your images in Flex because your browser is already doing that. While it is true that your browser is caching the images that your Flex app requests it probably works a little different then you think. For example the first time you load an image you might notice that it takes a second, but if you load that same url again it shows up right away. This must mean that it is using a cached version of the image right? Well thats partly correct your browser is giving you a cached version of the image BUT, your Flex app is creating a whole new instance of that image data. So by default you get a speed gain with your browsers cache but what you are not getting is any memory gains. Each time you load that image your Flex app’s memory usage will go up by the size of that image. This is because each Image component keeps a separate BitmapData for its own use. In some cases this is good but most of the time it is not necessary and can be wasteful.

If we cache the images in the app it self we can achieve even faster loading speeds because we do not even need to ask the browser for the image. Second and even better, we can reuse the same image over and over with almost no memory overhead. This is done by sharing the same BitmapData between multiple Image components.

How it works

ImageCache works by keeping a mapping between URL and BitmapData. When you use ImageCache to cache an image it will load the image and then store the BitmapData for that image. Then when you want to set an Image component’s source to that image ImageCache will create a new Bitmap using a reference to the stored BitmapData. This means that there is almost no memory overhead and the image will load almost instantly because we are just referencing the BitmapData instead of creating a whole new copy of it. One thing to note is that because of the BitmapData sharing if you change the underlaying BitmapData of one of the Images all of the Images referencing that BitmapData will also change. This may or may not be good for you depending on how your app works.

ImageCache currently has 4 public methods:

public function setImageSource(image:Image, source:Object):void
public function cacheImage(source:Object):void
public function flushImage(source:Object):void
public function loadIntoCache(source:Object):void

The setImageSource method allows you to set an Image’s source using the cache. If the url is not cached already this method will cache the image and set the Image component’s source. If the image is already cached it will just set the Image component’s source.

Next the cacheImage method will simply cache an image with out setting any component’s source. This is useful for pre-caching images so they can be used later on with out having to load them.

If you want to flush an image from the cache you can use the flushImage method to do so. This method removes an image from the cache meaning that the next time it is requested it will ask the browser.

Lastly the flush method will clear all images in the cache.

When you use the setImageSource method you do not have to worry about timing or whether or not the image has been cached yet because ImageCache already accounts for that. It will keep a list of Image components that want a certain source and once it has finished caching it will go back and set it on all the Images that were waiting.

One more thing. I require Image components but that could easily be swapped out for SWFLoader or whatever class you wanted. This is just a quick example to show the benefits of using caching in your app. The same techniques could also be used to cache any type of file your app might be loading .swf, .pdf, .xml and so on.

Advertisements

Maintaining transparency with BitmapData

This took me a while to figure out but it was really simple once I read the docs.

BitmapData.draw example

You want to use the BitmapData class’s draw method to get a “copy” of some thing in ActionScript. You simply create a new BitmapData and then use the draw method and all is well right? Not quite. If you are using the draw method on something that has transparentcy, like a .png image, you might notice that now all of your transparent pixels are white. This is not a bug it is simply because you have not properly set up your BitmapData. If you take a look at the docs BitmapData’s constructor takes a 4th optional parameter called fillColor. The fillColor is a unsigned int that defaults to 0xFFFFFFFF if you do not pass anything in. At first glance you might look at that default value and think hey there are two extra F’s in there, but that is indeed a correct value. The fillColor param is a 32-bit ARGB color value. This mean the first two F’s specify the alpha, then the next two the red, then green, and then blue. This color is used to fill the bitmaps image area and because it is set to 0xFFFFFFFF (solid white) by default you create an all white BitmapData.

Then when you call draw you are drawing on top of the already white BitmapData with the image that has transparency. It is no wonder all the transparent pixels turned white you are really just seeing through the image to the white background. Don’t worry this is very easy to fix just change the default fill color to something transparent like so:

var transBMD:BitmapData = new BitmapData(w, h, true, 0x00ffffff);

You can see here we set the fillColor to 0x00ffffff or white with alpha of 0, this means the BitmapData will have no background color and when we do the draw we will keep our transparency.

Here is a more complete example of the code.

var transBMD:BitmapData = new BitmapData(origImage.content.width * 0.5
    origImage.content.height * 0.5,
    true, 0x00ffffff); //Note the first two 0's mean the alpha level is 0

var trans:Matrix = new Matrix(); //a transform matrix
trans.scale(0.5, 0.5); //scale the image
transBMD.draw(origImage, trans); //draw original image but scale it
var img:Image = new Image();
img.source = new Bitmap(transBMD); //This image will be 50% smaller and still have the transparency

I should also note that if you use BitmapData.copyPixels it will preserve the transparency and is much faster than using draw, but does not allow for stretching, rotating, or adding color effects. If you are not going to be doing any of those copyPixels is a better choice because of it’s speed.

Here is a link to a live Flex example with view source enabled that shows how this all works.
BitmapData.draw example

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.

Performance issuses when using trace

The other day I was working on a custom component that could be dragged and resized, and in my updateDisplayList method I was tracing a couple things so I could see what was going on. I noticed some very drastic slow downs and I was pretty sure that it was my trace statements causing to much I/O overhead. Anyway this got me wondering so I created some tests to see just how much the trace statement can affect performance of a Flex App, because I have seen and written many lines of code where not all of the trace statements are removed before release builds. This used to no be a problem because inside of Flash we could choose to omit traces from our published version of the swf, but when writing Flex correct me if I am wrong there is built in way to remove traces.

Below I have made some examples to show the performance hits that come along with those extra traces. All of the examples here have been built using Flex builder release build.  While a trace here and there may not be to bad if they sneak their way into a loop or a validation method, which gets called very often, they can seriously slow your app down.

Want proof? Read on

I put together a couple Flex apps to demo how trace can slow down your app.  I decided that I will create a function that simply loops for a specific amount of time, in this case 100 milliseconds, and increments a counter with each iteration.  In these examples there is a button that will start the loop and once the loop has completed the total number of iterations will be displayed.  Now because there is no good way to include these swfs in this lovely wordpress blog below are links to where you can see these in action.
Trace Tests

The results tell the tale

I ran these tests on my laptop which has a dual core 2.5 with 4 gigs of ram and here is what I saw.  When I ran the test with traces I saw on average 500 iterations with the debug version of flash player and 60,000 with the normal version.  Then I was surprised when I ran the test with out traces where I saw around 900,000 iterations.  All I can say is wow, I mean I knew I/O was expensive but this was a much bigger difference than I thought there would be.  Now you might be thinking why do the trace statements even effect the performance here, because after all there is nothing being output.  But infact the traces are still happening even though you can not see them, for instance if you have the debug version of the flash player you can view these traces in the flashlog.txt file.  This is why the debug versions numbers were so low because each trace causes disk I/O.  This is another reason not to trace to much because someone could be reading your traces.

What can you do?

Another way is to wrap your trace statments in a conditional.  See the example below.

Conditional Trace Test 

Yeah I know you would not use a checkbox to control your traces in a real application you would be much better off setting a constant.

    private const DEBUGGING:Boolean = true;
    .
    .
    .
    if (DEBUGGING) {
        trace("what ever");
    }

Ok so thats not to bad but it still requires a code change to go from debug mode to release mode.  

As another alternative you could write a script to preprocess your ActionScript that removes all the trace statements before they you compile.  Not sure about you but I would rather not have a script messing with my code.

The better way to use trace

Thanks to ActionScript 3 we can now do compile time conditionals. Basically we set a variable during compile time that we can reference which we can reference in the code.  Again you will wrap your trace statements in a conditional but this time it will look a little different:

    CONFIG::debugging {
        trace(counter);
    }

Now some of you may have not seen anything like this before.  What this code is doing is checking for a compile time variable called “debugging” and if it is set to false the trace will be skipped if debugging is true of course you will get your trace statement.  This is pretty cool because now you can switch from debug to release with out changing any code. To add a compile time variable you simply use the following syntax to to your command line mxmlc or to the compile options in Flex Builder.

    -define=CONFIG::debugging,false

This works in both Flex Builder and via command line mxmlc or what ever else you use e.g. ant.  The code above would of course set debugging to false effectively removing all trace statements.  Then when you need to debug simply rebuild the swf with

    -define=CONFIG::debugging,true

and magically your traces will come back.  For more information on conditional compilation see Adobes site http://livedocs.adobe.com/flex/3/html/help.html?content=compilers_21.html.  Of course I have some examples to show you.  Keep in mind that both of these swfs were compiled from the EXACT same code the only change was in the compile options that were used to build it.

Compile Time Test

Conclusion

Well as you could see from the above examples while the trace statement is probably one of the easiest ways to do some simple debugging it can cause some performance issues. Anyways just keep in mind what I have talked about and use tracing only when necessary and try to remember to remove them when you are done.  If you can not remove them try wrapping them in a compile time conditional.

I thought that I would write a little tutorial showing how to create a Flex application using the Adobe Flex SDK. The Adobe Flex SDK is a great tool because of how powerful it is an also because it is 100% free. I will cover where to get the Flex SDK, how to write mxml, and finally how to compile the application.

First Things First – Getting the Flex SDK

Before you can build any Flex applications you will need the Flex compiler (aka mxmlc). Not to worry you can get this for free as part of the Flex SDK. You can find the SDK on Adobe’s site or use the link below. Flex 3.3 SDK will work on all platforms.

http://download.macromedia.com/pub/flex/sdk/flex_sdk_3.zip

Once the download is complete you will need to extract the files from the zip. You can extract it anywhere you want, for the rest of this tutorial I will be assuming you extracted it into C:\flex_sdk_3. The main file you will be needing from here is mxmlc.exe which will be inside the “bin” directory (e.g. C:\flex_sdk_3\bin\mxmlc.exe).

 

Showing files extracted files for the flex sdk

Showing files extracted files for the flex sdk

 

 

We will come back to this compiler after we have some code to use it on.

Lets Write Some Code

We will be created just one file for this tutorial, so where every you would like create a new file named helloworld.mxml. I suggest making a folder for each of your Flex applications just to help keep things clean. For this example I created a folder called “hello world”. This file will simply be a text file so you can use what ever editory you like be it notepad, wordpad, emacs, jedit, ect, I will be using vim because its the best. The language used to write Flex applications is called MXML and like the name implies it is a form of XML so each MXML file needs to start with the following line at the very top.

<?xml version="1.0" encoding="utf-8"?>

Now lets add some actual MXML code, we will start with the <mx:Application> tag. This is the first tag that all of your Flex applications will start with. This is similar to how all HTML pages start with an <HTML> tag. Below is code for the most basic Flex app you coild possibly write.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
</mx:Application>

Here is a screen shot of me editing my mxml file.

 

Screen shot of editing helloworld.mxml using vim

Screen shot of editing helloworld.mxml using vim

 

 

Believe it or not this is enough code to compile so lets do that before we go any further to make sure that everything is working

Compiling Your Flex with mxmlc.exe

So we wrote a little code and now we want to see what it will produce. We will be using mxmlc to compile this mxml into a swf. So it is time for you to remember where you extracted your Flex SDK, I put mine in C:\flex_sdk_3 so I will be referencing that location, if you have it somewhere else be sure to make the appropriate changes to my instructions. Once you locate your SDK folder you will want to look inside for a folder called “bin”. It is inside of this bin folder that you will find the mxmlc compiler. There are two ways that you can use this compiler, the first and most simple way is to simply drag your mxml file and drop it right on top of mxmlc.exe. You will see a window open while mxmlc is running, which will close as soon as mxmlc is done. Assuming all goes well you will find a freshly made swf called helloworld.swf inside the same folder as your helloworld.mxml. While this way may seem super simple it has several draw backs. If there are compile errors you will not be able to see them because the window closes immediately. Secondly you will not be able to add any extra compile options using the drag and drop method. I suggest using the second method of running mxml from the command line. If you are in windows XP you will need to click on the start menu then click “run” and then type “cmd” and press enter. This will open up a new window with a command line. In Vista you simply click start menu and type “cmd” in the search box. Once you have the prompy open you will have to move to the directory where your helloworld.mxml file is located. Now to compile your Flex you simply run mxmlc and pass it helloworld.mxml as a parameter. To do that run the following command on the command line.

C:\flex_sdk_3\bin\mxmlc.exe helloworld.mxml

Here is a screen shot of mxmlc running on my computer.

 

Screen shot of running mxmlc from the command line

Screen shot of running mxmlc from the command line

 

 

Again once mxmlc is done running you will have a helloworld.swf in the same folder as you helloworld.mxml or you will see some sort of error message from mxmlc. Like I said before if you run the swf you will see nothing more than a blue background.

 

Screen shot of helloworld.swf

Screen shot of helloworld.swf

 

 

Lets add some more code

So we made an app if you can call it that so now lets do something a little more interesting. We will be using the <mx:Label> tag to display some text in our app. The <mx:Label> tag has a text attribute that allows you to set the text that you wish to display. See the code below:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Label text="This is my first app"/>
</mx:Application>

Now you should compile this again just how we did before. After you have compiled your mxml again if you run this swf it should like something like this.

 

running helloworld.swf with a Label

running helloworld.swf with a Label

 

 

Now lets add one more thing to this app before we call it a day, a Panel component. To do this we will use the <mx:Panel> tag. A Panel is similar to a window, it has a border and a place for a title. Lets take a look at some code.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Panel title="Hello World">
        <mx:Label text="This is my first app"/>
    </mx:Panel>
</mx:Application>

Again you should compile this code and see what we have now. Here is a screen shot of what it should look like.

 

Here is what the final swf looks like

Here is what the final swf looks like

 

 

Thats it

Well thats it for now I know this was a very simple example but I just wanted to get you used to using the compiler and writing some mxml. I hope I sparked your interest in Flex and you will continue to experiment and learn. Here is a link to the Flex 3.3 documentation:

http://livedocs.adobe.com/flex/3/langref/