Friday, October 26, 2007

A filed weird behaviour - The component doesn't render correctly after adding to Stage

Apart from sharing Flex Programming experience, this blog also serve as a record or notes for some weird scenerios...

There were once I working on a slide show project. Basically a container is moving along the y-axis and thumbnails are adding dynimatically to the container. But somehow the thumbnails are not rendered on screen. The codes are executed as I debug'd them and does show the lines.

The thumbnails show up if I stopped the moving container. This is weird to me.

Finally, I found a dirty solution, i.e. add the thumbnails container to rawChildren.

It seems the issue is related to the render sequence of rendering...
e.g. Initialize component -> set properties -> updateDisplayList -> commitProperties and so on...

Wednesday, October 17, 2007

Set the verticalScrollPosition

Sometimes we want to set the scrollerbar position by actionscript, that can be easily achieved by:
verticalScrollPosition = maxVerticalScrollPosition;
however, this won't work right after we added some childs to a container.
The flash player need to refresh the changes in order to calculate the right position.

To move to the right position, you may try this:
validateNow();
verticalScrollPosition = maxVerticalScrollPosition;

Tuesday, October 16, 2007

Add Listeners to ImageProxy used in mx.managers.DragManager

Ran into another problem on my "Houngan" Project.

I want to drag an Image using DragManager.
And I applied imageProxy in the doDrag function and it works fine.

However, I want to hide the original image, which remains at the position it located, when I dragging the imageProxy.
So I tried the following steps:


  1. click on the original image, broadcast mouse down event
  2. execute the onMouseDown function, hide the image.
  3. make an imageProxy
  4. execute DragManager.doDrag function and move the imageProxy by following
DragManager.doDrag(initiator, ds, event, imageProxy, 0, 0, 1, true);

Yes I can hide the original image and drag the imageProxy, but the release of imageProxy doesn't resume the original image's visible stage. There is no event broadcasted from DragManager on this as far as I know. (Please kindly tell me if you do know one ^^)

I went over the source code of DragManager and discover there is a imageProxy variable in DragManagerImpl.as
And whenever endDrag is called, the imageProxy is removed from the parent container. So there is a way:


  1. click on the original image, broadcast mouse down event
  2. execute the onMouseDown function, hide the image.
  3. make an imageProxy and add event listener to it for the Event.REMOVED event.
  4. execute DragManager.doDrag function
  5. execute listener handler when Event.REMOVED is detected from imageProxy.

So that's the trick =)

Friday, October 12, 2007

Memory Leak in Flex

Here comes my first case study: Memory leak by using Bitmap & BitmapData.

Currently I cope with a project which need to load external JPEGs into Flex and forming BitmapData objects. I will do some operations on the BitmapData, then put it into the Application.

During the application runtime, I will remove those bitmap display objects, but I discover the garbage collection doesn't really release memory from the application, so there is a memory leak. (The memory used up to 350M after I afk 30mins)

I study gskinner's
AS3: Resource Management pt 2, and carry out some test as following:

private function onBitmapLoadComplete(event:Event):void
{
var bitmapDataProxy:BitmapDataProxy = event.currentTarget as BitmapDataProxy;
bitmapDataProxy.removeEventListener(BitmapDataProxy.LOAD_COMPLETE, onBitmapLoadComplete);

var bitmap:Bitmap = new Bitmap(bitmapDataProxy.result.clone(), "auto", true);

var bitmapContainer:UIComponent = new UIComponent();
bitmapContainer.addEventListener(MouseEvent.CLICK, onMouseClick, false, 0, true);
bitmapContainer.addChild(bitmap);
this.addChild(bitmapContainer);

bitmapDataProxy.destroy();
bitmapDataProxy = null;
bitmap = null;
bitmapContainer = null;
}

private function onMouseClick(event:MouseEvent):void
{
var bitmapContainer:UIComponent = event.currentTarget as UIComponent;
bitmapContainer.removeEventListener(MouseEvent.CLICK, onMouseClick);

bitmap.bitmapData.dispose();
this.removeChild(bitmapContainer);
bitmapContainer = null;

bitmap=null;
}

Checked with Flex Profiler, the Memory usage up to 4279k at the loading of BitmapDataProxy.
After the loading is complete, I have trashed the BitmapDataProxy after putting the BitmapData into a Bitmap. This can be observed by observed used memory dropped to 1666k after I press the garbage collection button in Profiler. However, weird stuff came...

After I clicked on the image and removing the child. The used memory doesn't further drop down. And by observing Loitering Objects, I see there are still a bitmap object and BitmapData in the memory. So probably I can't clear it.

By further test, I found that The BitmapData left in memory is referring to the property of Bitmap, i.e. Bitmap.bitmapData. I have clear it, but I need to remove the reference in order to release the counter of reference to the object in memory.

By adding the code, I further dropped the used memory to 1141k. And there are no more BitmapData instance in the memory. but there is still one Bitmap instance. so I guess the removeChild doesn't really remove all the childs in the Display List.

bitmap.bitmapData.dispose();
bitmap.bitmapData = null;


Finally I added following code to remove the unused Bitmap instance:

bitmapContainer.removeChild(bitmap);

I finally can remove all the Memory Leakage problem in this little revising practice. I think there are much more to go over my Album Project, with project coded "Houngan".

Uhmmm, at least I see hope through this practice. And wish it helps you too.

The Finalized code as following:

private function onBitmapLoadComplete(event:Event):void
{
var bitmapDataProxy:BitmapDataProxy = event.currentTarget as BitmapDataProxy;
bitmapDataProxy.removeEventListener(BitmapDataProxy.LOAD_COMPLETE, onBitmapLoadComplete);

var bitmap:Bitmap = new Bitmap(null, "auto", true);
bitmap.bitmapData = bitmapDataProxy.result.clone();

var bitmapContainer:UIComponent = new UIComponent();
bitmapContainer.addEventListener(MouseEvent.CLICK, onMouseClick);//, false, 0, true);
bitmapContainer.addChild(bitmap);
this.addChild(bitmapContainer);

bitmapDataProxy.destroy();
bitmapDataProxy = null;
bitmap = null;
bitmapContainer = null;
}

private function onMouseClick(event:MouseEvent):void
{
var bitmapContainer:UIComponent = event.currentTarget as UIComponent;
bitmapContainer.removeEventListener(MouseEvent.CLICK, onMouseClick);

var bitmap:Bitmap = bitmapContainer.getChildAt(0) as Bitmap;

bitmap.bitmapData.dispose();
bitmap.bitmapData = null;

bitmapContainer.removeChild(bitmap);

this.removeChild(bitmapContainer);
bitmapContainer = null;

bitmap=null;
}

Thursday, October 11, 2007

Finally ... my first post!


Hi all, I decided to register an account and make it up finally.
The purpose of this blog is to record my Flex Learning Career, and share some of the experiences.

I am a Multimedia Engineer and the company I worked starting to adopt Adobe Flex as the solution against various projects.

Personally I start to study Adobe Flex when it is released at beta 2.0, and wrote some stock quoting program. The functions are simple but still somehow I feel good with it.

When I go deeper with it, I started to find there are many problems to deploy corporate-wise solutions with Flex. So I started to study Cairngorm, which is a Micro Architecture Programming Framework initialized by Steven Webster and his colleagues.

The Cairngorm improved my production speed a lot, with the help of Cairngen...


I found that there are many place a Flex Engineer need to be careful, for example, memory leak, which may continously consume the resource of client's computer and eventually hang user's computer. I will post more in the coming days.

haha... Got to go for lesson, bye~

//testing of posting code
var foo:Object = new Object();
foo.name = 'camus';