¿Cómo descargo un archivo SWF cargado externamente desde un componente SWFLoader en Adobe Flex?
air (7)
Tengo una aplicación que carga archivos SWF externos y los reproduce dentro de una aplicación Adobe Flex / Air a través del componente SWFLoader Flex . He estado tratando de encontrar una forma de descargarlos de un evento de clic de botón. Tengo Google ''s ampliamente y nadie parece haber podido hacerlo sin un truco. La combinación de código que veo que usan las personas es:
swfLoader.source = ""; // Removes the external link to the SWF.
swfLoader.load(null); // Forces the loader to try to load nothing.
// Note: At this point sound from the SWF is still playing, and
// seems to still be playing in memory.
flash.media.SoundMixer.stopAll();
// Stops the sound. This works on my development machine, but not
// on the client''s.
Si los SWF están cerrados (ocultos) de esta manera, eventualmente el programa se bloquea.
¿Algunas ideas? He encontrado toneladas de mensajes en varios foros con personas que tienen el mismo problema. Supongo que obtendré una respuesta incorrecta / incompleta aquí, y que mi publicación se hundirá en la nada como de costumbre, pero de cualquier forma, ¡gracias de antemano!
Edición 1 : No puedo editar las películas SWF reales, las crea el cliente. Si no puedo cerrar ningún archivo SWF abierto a través de Flex, ¿no es un problema con la arquitectura Flex? ¿Es mi única opción enviar los archivos SWF al navegador web?
El problema reside en el swf cargado, simplemente no limpia el audio después de sí mismo. Intente adjuntar un evento de descarga en clips de película como este:
MovieClip(event.target.content).loaderInfo.addEventListener(Event.UNLOAD, unloadMovieClipHandler);
private function unloadMovieClipHandler(event:Event) : void
{
SoundMixer.stopAll();
}
Es un problema que un SWF mal creado pueda afectar su aplicación, y muchos de los problemas con esto se solucionarán en Flash Player 10, como han mencionado otros. Sin embargo, independientemente de la plataforma, siempre correrá el riesgo de tener problemas si carga un código de terceros, siempre existe la posibilidad de que contenga errores, fugas de memoria o un código francamente malicioso. A menos que pueda cargar contenido en un entorno limitado (y no puede hacerlo en Flash, al menos no todavía), cargar cosas malas afectará su aplicación, es así de simple.
Lamento decir que, a menos que pueda garantizar la calidad del contenido cargado, no puede garantizar la calidad de su propia aplicación. Los desarrolladores de Flash son conocidos por escribir cosas que tienen filtraciones, o que no se pueden descargar, porque Flash hace que sea fácil hacer algo incorrecto, especialmente para las cosas que viven en la línea de tiempo. Cargar cualquier contenido Flash que no tenga control directamente es muy peligroso.
Pruebe lo siguiente:
try {
new LocalConnection().connect(''foo'');
new LocalConnection().connect(''foo'');
} catch (e:*) {}
Eso forzará una rutina de recolección de basura. Si su SWF todavía está conectado, entonces ha perdido algún tipo de conexión, como el audio.
Hay un par de formas de forzar a GC, que todo es malo porque aumentan la CPU, pero la buena noticia es que viene una forma oficial en Flash Player 10:
unloadAndStop
enlace: http://www.gskinner.com/blog/archives/2008/07/unloadandstop_i.html
Hasta entonces, me temo que tendrás que forzarlo con hacks como lo mostré arriba.
... ¿no es un problema con la arquitectura Flex?
Sí lo es, y también afecta a Flash en general. Hasta que pueda aprovechar el método Loader.unloadAndStop () en FP10 (AIR 1.5), no puede garantizar que el contenido cargado externamente no siga consumiendo recursos de memoria y CPU, incluso si usa el método Loader.unload()
. (Para ser sincero, no estoy 100% seguro de que incluso eso garantice la liberación de recursos, pero tal vez soy un pesimista).
Lo mejor es que insista en que los creadores del contenido que carga cumplan con un conjunto de directrices, incluida la exposición de algo así como un método dispose()
que su aplicación puede llamar para pedirle que libere la mayor cantidad de recursos posible antes que usted unload()
. Si esto no es posible, su aplicación casi definitivamente se hinchará en la memoria y el uso de la CPU cada vez que cargue un swf externo. Lo siento.
Si te hace sentir mejor, no estás solo. ;)
En general, me mantengo alejado de SWFLoader y uso las clases en el paquete mx.modules.
Flex tiene un sistema de módulos que permite este tipo de comportamiento. Puede consultarlo aquí: http://livedocs.adobe.com/flex/3/html/help.html?content=modular_3.html . En general, la carga dinámica y la descarga de componentes SWF es complicada, especialmente si esos módulos modifican cualquier estado global en la aplicación (estilos, etc.). Pero si crea una interfaz para sus módulos y luego cada clase que carga / descarga implementa esa interfaz y extiende la clase de módulo flexible, puede cargarlos y descargarlos limpiamente.
La mejor solución es
swfLoader.autoLoad = false;
swfLoader.unloadAndStop();
swfLoader.autoLoad = true;
De esta manera, detiene al jugador, descarga el contenido de la memoria y evita que el sonido siga sonando. Saludos
No ha mostrado todo su código, así que supongo que no usó el método de descarga de la clase Loader. También swfLoader.load (null) me parece incorrecto ya que el método de carga está esperando un objeto URLRequest. Cuando desee limpiar las cosas al final, establezca el valor del objeto en nulo en lugar de llamar a una carga nula. El hecho de que el audio que aún está escuchando indica que sus datos no se descargaron, o que el archivo de audio no se encuentra dentro del contenido que se descargó. Vamos a caminar a través de esto.
Ejemplo a continuación
function onSwfLoad(e:Event):void
{
addChild(loader);
loader.contentLoaderInfo.addEventListener(Event.UNLOAD, onLoaderUnload, false, 0, true); loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onSwfLoad, false);
}
function onLoaderUnload(e:Event):void
{
trace(''LOADER WAS SUCCESSFULLY UNLOADED.'');
}
//Now to remove this with the click of a button, assuming the buttons name is button_mc
button_mc.addEventListener(MouseEvent.MOUSE_DOWN, onButtonDown, false, 0, true);
var loader:Loader = new Loader();
var request:URLRequest = new URLRequest(''test.swf'');
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSwfLoad, false, 0, true);
function onButtonDown(e:MouseEvent):void
{
loader.unload();
loader.contentLoaderInfo.removeEventListener(Event.UNLOAD, onLoaderUnload);
//When you want to remove things completely from memory you simply set their value to null.
loader = null;
button_mc.removeEventListener(MouseEvent.MOUSE_DOWN, onButtonDown);
}