I went to Fox news a few minutes ago to check out news on the plane that crashed into the Hudson after striking a bird out of Laguardia. Turns out Fox news has added an Adobe Air app to watch their live and streaming news with. The flash based webpage option still exists, but this is pretty new I believe. It seems to work well but is pretty basic.
Category: Adobe Air
Goal: Have a pop-up with a max width of a certain percentage of the screen, but shrink and grow the height of the pop-up based on the size of the content.
I had expected this to be a more built-in feature, but when it wasn't [per my findings] I wrote this AutoResizeHTML extension of MX:HTML. I tried several other approaches and measuring methods that worked, but none that were as consistant and bullet proof as this; but if you know of a better solution than mine, don't be afraid to critic me...
- On the Event.HTML_RENDER event I create a new HTMLloader with a pre-set width to the new maxAutoWidth which in my case is 30% of the current screen width.
- load the new HTMLText from 'it's self'.
- Perform a secondary measurment of the HTMLText to check to see if 30% of the screen is too big.
- If it is too big, I use that number instead. There is no need to check the height, because that number should always be correct.
- If the number is not too big, I resize it's self with the measurements given by the HTMLLoader.
Here is an example of my caller:<xMx:AutoResizeHTML
id="display"
htmlText=""
color="#000000"
horizontalScrollPolicy="off"
verticalScrollPolicy="off"
maxAutoWidth="{maxAutoWidth}"
x="5"
y="5"
/>
Download the latest version of AutoResizeHTML (source code & example)
I'm working on a screen saver for cooporate use that I've choosen to use Adobe Air for. Once I started building and installing my first tests I ran into a few things I didn't like when clicking the preview and settings buttons in the display properties of Windows. I decided to open up a small number of choices to the users by actualy giving them a "User Options" window. Windows is kind enough to pass some arguments along, so this was actualy pretty easy.
/c = Settings Mode
/p = A preview mode
/s = Run as Screen Saver (when you click preview or computer times out)
Step one was to create a listener set. In my case I put this in my top level application instead of my EnvironmentControl.as [in my Model-Glue-Flex framework] because I wanted to keep the entire app from initializing for a settings mode.
private function onPreInitialize():void {
NativeApplication.nativeApplication.addEventListener(InvokeEvent.INVOKE, onArgumentsPassed);
}
private function onArgumentsPassed(e:InvokeEvent):void {
if (e.arguments.indexOf("/p") != -1) {
this.exit();
} else if (e.arguments.indexOf("/c") != -1) {
this.settingsMode = true;
}
}
You'll notice that I have exited the screen saver on the preview mode. I did this because I found it annoying that windows would auto-launch the screen saver both on entering the tab in display properties as well as after saving and closing the settings window; These are the only two instances that the "/p" comes up in the arguments. The preview mode is suppose to launch the screen saver into mini-mode inside the faux computer screen in the pop-up, but I'm not sure how to do this or care to at this point.
I'm currently working on an Adobe Air based screen saver (technology choosen for ease of communicating to a central server). Things were going along well until I started to do performance testing today and I realized that garbage collection was not freeing up what I expected it to be.
To sum up my app very briefly I have a Canvas component that wraps an Image componant in order to give the apearance of a poloroid photo. When I get past a certain threshold I remove these wrappers via a removeChildAt(0) to sluff off the oldest image, freeing up space and memory. Turns out nothing was actualy being cleaned up. I found some good resources on garbage collecting that informed me of a few things I didn't know (specific to flash) but nothing got me closer...
Then the light upstairs randomly turned on and I thought, well if I there isn't anything on the outside of the wrapper holding on to it (such as an event listener), maybe there is something on the inside. This might seem like an obvious place to look, but my wrapper was only a handful of lines long and did absolutly nothing but look pretty... However due to the fact that I'm pulling images from a server down to the local disk (which is all done way prior to trying to draw to screen), my image source looks like this: new File(imagesDir.nativePath).resolvePath(aPhoto.name).nativePath.
SOLUTION:
In order to get garbage collection to work, I wrote a quick function inside my wrapper:
public function compact():void {
(this.getChildAt(0) as Image).source = "";
this.removeAllChildren();
}
I call this function first, then poof.... all my garbage collection works as "expected". Not only am I suprised that this worked, I'm suprised that I had to do this. Why on earth wouldn't an image get removed if it's container was destoyed?
Also, I ran tests without the this.removeAllChildren(); while garbage collection still worked, the overall average memory usage went up almost 650k for some reason.
Relate Reading:
About garbage collection
Why is the memory usage of my Flex app not coming down?
Garbage Collection and Memory Leaks