I'm currently building an air app with FB 4.
I have a custom control that contains a VideoDisplay control, and which loaded using the PopupManager.
Using the profiler, i've noticed that every time the my popup is loaded the memory for it gets allocated, but when it's closed the memory is never recovered.
There's nothing else holding a reference to the popup. And if I don't set the source of the VideoDisplay object, then there is no leak - but as soon as the source is set I get a leak.
I can't see any method to force close the stream or anything on the spark VideoDisplay control.
Any idea or suggestions?
EDIT: I have tried setting the source to null before closing the popup but that doesn't change anything.
Also, I'm not holding any event listener to the video.
Edit 2: It doesn't happen if I replace the spark VideoDisplay with an mx VideoDisplay. Bug in the spark component?
I dont have a solution, but just wanted to add that I have had the same issue.
I have a 'screensaver' which just loops the same video over and over (and over...). The component is initialized (but hidden and paused) when the app starts, and comes into view when the app is idle.
Each time the video restarts, more memory is allocated even though it is the same video and only 'play' is called (the source never changes).
I think your assumption of a bug in the spark component is correct as by replacing the videodisplay with the old mx component fixed the issue.
Related
We are currently testing parts of our application that open in popup windows. These windows are subclasses of TitleWindow. The issue we now run into is that the popups seems to be registered multiple times and that tests are sometimes executed on popups that have already been closed (or so it seems).
I thought this had to do with the way we closed and removed our popups, but I can't really spot any problems there. After looking into the FlexMonkey source code, I saw that there is an explicit check for "TitleWindow" in the ADDED_TO_STAGE handler, after which the popup is added as an application window. But the popup never seems to be removed from the "_windows" collection. As a result, when you open the tree view in FlexMonkey, there are several instances of the same popup window class. This probably also explains why our tests sometimes do not seem to run (visually), but execute and verify correctly, as they are ran on a hidden instance of a popup. I would expect the MonkeyAutomationManager to also listen to REMOVED_FROM_STAGE events and remove the popup when it is closed.
Am I missing something here or is this an (known) issue?
My guess is that it isn't an issue, it's simply that your code isn't properly cleaning the object and removing it from the display list. You also need to remember that garbage collection does not run right after you remove something from the stage. It could be possible that your window, even if it has been removed from the stage is in fact still listening and responding to events.
I would like to know the correct way to close an AIR application programmatically.
In my Spark WindowedApplication I have:
this.addEventListener( Event.CLOSING, shutdownApp );
and of course an implementation of the shutdownApp method (which basically tidies up temporary files).
This works fine for the top-right close button of the window. However I also have functionality which needs to shutdown the application. Within the code I have called:
NativeApplication.nativeApplication.exit();
However this doesn't trigger the Event.CLOSING method, and so my temporary files are not cleared up. Should I not be calling nativeApplication.exit ? If so, what should I call instead? I'd rather not have to call my shutdownApp method before the NativeApplication.exit() as this doesn't feel quite so elegant.
Can anyone shed any light on the correct way of doing this?
Thanks,
Phil
I know this question has been answered and accepted, but thought I'd share, I use.
stage.nativeWindow.close();
The documentation looks a bit ambiguous on this and I would have the same interpretation that you did. Did you try the close or exit methods on the WindowedApplication?
Something like this, with FlexGlobals and topLevelApplication:
(FlexGlobals.topLevelApplication as WindowedApplication).close();
or
(FlexGlobals.topLevelApplication as WindowedApplication).exit();
Just give an answer here because I searched for a related question and was not able to find sth.
I wanted to do something similar and close an AIR application when the native close button of the document window (spark.components.Window) is pressed thought that the spark WindowedApplication container (the applications main window) is still active to hold and manage the native menu (at application startup it is also used to display a splash screen. It has to stay open since if it is closed the native menu won't show up or be accessible anymore so its visible property is just set to false).
My main problem was the window closing event. Registering it with ActionScript like
this.addEventListener(Event.Closing, windowClosed);
does not work: No closing event was dispatched.
The only way was to register an event handler directly in the s:Window element at start of the MXML file. I just throw in the closing attribute:
closing="window1_closingHandler(event)"
The event was dispatched then and in window1_closingHandler-function I called
NativeApplication.nativeApplication.exit();
That works for me and shuts down the whole application.
I have a videoDisplay object in a popup.
When I remove the popup the video continues to play.
How do I remove the videoDisplay object from memory?
I have tried setting the variable to null but with no luck. I can just call the stop() function and forget about it but am wondering whether this won't come back and bite me.
Any help much appreciated.
Stopping would be enough. Remove any event listeners attached to it to make sure that it is garbage collected. If the control is is streaming from the Flash Media Server, call the close() method after calling the stop(). The close method forces the close of an input stream and connection to Flash Media Server.
Anybody that happens to know how to do this would really be helping me out.
Maybe its simple, I don't know, but it involves embedded SWF's so I imagine it could entail interacting with event handlers or methods in an embedded SWF.
But anyway, here it is:
I have several embedded SWF's on a canvas (in SWFLoaders) and when one of them changes visually I need to know which one changed.
The 'render' event provides only part of the solution:
If an SWFLoader contains a videodisplay there are continual render events generated in the parent app while that videodisplay is running. If the SWFLoader just contains some static input control otoh, there are no render messages in the parent app until someone interacts with that control and changes it visually, and then there are render events broadcast in the parent app. So, this is clearly part of what my requirements are.
The problem with the render event however, is that it does not tell you which embedded SWF actually changed (in the target or currentTarget.)
But I need to know which one changed.
(Are there seperate render messages being generated within an embedded app (seperate from those in the parent app) for example, that could be detected.)
My solution is as follows:
When a render event occurs, I check if there is a visible swfloader within the browser window, and then I do a BitmapData.draw of its contents to a bitmapdata which is saved. With each new render event, I compare 10% of the pixels of the saved bitmap to the new bitmap and that will tell me whether or not the embedded .swf visual content has actually changed. a 10% sample has proven to be more than sufficient (just iterating through the vectors of the respective bitmaps with the vector index incrementing by 10, instead of 1.)
BitmapData.draw is plenty fast and iterating through 10000 vector elements is like a millisecond.
I came across this topic today while investigating something very strange. Doing certain things in our Flex app can cause the number of frames rendered to rocket, from 12fps to ~30fps: loaded animations start playing at high speed and the GUI starts to lock up.
Since everything I've read on Flex/Flash hammers home the point "the frame rate is capped at the fps set in the top level app", it seems the only way these extra renders can be happening is due to some events causing them (no programmatic changes to the stage's framerate are done anywhere). Since it only happens when I put my update logic in the ENTER_FRAME handler, I'm trying to figure out what might be happening which to apparently causing Flex to go render-crazy.
Hypothesis: something in my update function is triggering an immediate screen update, this raises another ENTER_FRAME immediately, which means my update loop gets called, which triggers another immediate screen update, ...
We have Flex components used in our GUI, if this is a factor. I don't really know where to go next on this.
Clarifications:
When I say things speed up, there
are two ways this manifests.
Firstly, my ENTER_FRAME handler gets
called far more often.
Secondly, a
loaded Flash SWF with a looping
animation built in suddenly speeds
up to te point it looks silly.
I am not using updateAfterEvent, I only
found this existed when researching
this problem. Apparently, some
events on Sprite subclasses
automatically call this and I wonder
if that's the root cause.
I am not doing any direct messsing about with rendering at all. Background animations play automatically as they have timelines built-in from CS3 authoring, all our update function does is change the position of DisPlayObjects or add/remove them etc
Update:
I added a label to my app to print out stage.frameRate, and discovered at certain times, it suddenly changes from 12 to 1000 (the maximum allowed value). While it was trivial to add a line to my ENTER_FRAME handler to reset it that's hardly a big help.
Also, even doing this, the rendering is all messed up. Certain actions (like raising an Alert popup) make it all spring back into life.
Unfortunately, I am not able to view the source of the Stage class to set a breakpoint on the setter property.
That's very interesting about the Flex loading 'set to 1000fps' thing. What we have are several Flex applications which all provide a common interface. A master app is in charge of loading these modules as required through the SWFLoader class. However, the loading process already takes into account the delayed loading... when the SWF loads we then wait for the APPLICATION_COMPLETE from the SystemManager. Once this is received, shouldn't the applications completion have occurred?
Flex sets the frame rate to 1000 during "phased instantiation" of Flex components, which occurs only during initial load of a flex swf. This allows it to build all components very quickly.
Are you waiting for the Flex app to be fully loaded and constructed? You should be waiting for FlexEvent.CREATION_COMPLETE before working with your Flex content.
If you would like a reference to where this occcurs, look in the Flex LayoutManager class, line 326 (using Flex SDK 3.0.194161), in the setter for the property usePhasedInstantiation.
Update:
APPLICATION_COMPLETE should have you covered for the initial load.
This actually happens any time components are created directly from MXML. So there are a few other cases to look for. Are you using any Repeaters? Do you use any navigation containers that are building their children on demand?
One thing I'm not clear on - are you seeing that the actual screen refreshes are occurring faster than the published framerate? Or is it that your animations are moving faster but the screen refreshes are unchanged? (i.e., it used to move 10 pixels per second, but now it moves faster than that, regardless of how often the screen is drawn.)
An easy way to check this would be to try publishing your content at 1 fps. It should be clear whether the screen is redrawing once per second, but animated elements are being moved more frequently than that, or whether the screen is actually updating more frequently.
If the latter, are you using any updateAfterEvent() methods in your code? This can cause actual screen refreshes to occur faster than the published framerate. It shouldn't affect ENTER_FRAME events though. You should still only get one of those per frame update.
Alternately, are the things you're animating just Sprites and so on, or are you implementing them as Flex components, and trying to redraw them with invalidate() methods and RENDER events and so on?
If you could clarify a few of these points in the question the answer might be clearer. Thanks...
Thanks for the clarifications. If a loaded clip with a animation (I assume you mean a frame animation) is speeding up, then that certainly sounds like something is changing your playback framerate, as opposed to other things that could be going on. With that said it's not a problem I've seen crop up before, but I do think there are some things you could try that ought to narrow down where the problem is:
You might as well try tracing out stage.frameRate during the speed-up. Presumably nothing ought to be changing your framerate, but since that would explain your issues you might as well rule it out.
Try removing as many GUI components as possible and seeing if the problem still occurs, if it's possible to trigger the problem without them.
One sanity check you could try, if it's feasible, is to copy some of the contents of your game into a fresh project and try it there. Sometimes mysterious issues like this happen because some class or SWC is being imported somewhere that everyone forgot about.
You could try driving your code from a different event. For example, as far as I know driving it from Event.EXIT_FRAME or Event.FRAME_CONSTRUCTED ought to look the same, but if it doesn't then that's a hint. Alternately, you could try driving it from something like a keyboard event or MouseEvent.MOUSE_MOVE. Then if updates occur even though you're not firing events, you'll know something else is driving things besides your event loop.
Those are the things I'd try, anyway. Hope you track it down...