¿Cómo descargo un archivo SWF cargado externamente desde un componente SWFLoader en Adobe Flex?

StackOverflow https://stackoverflow.com/questions/117900

Pregunta

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 manera de descargarlos desde un evento de clic de botón.He buscado en Google por todas partes y nadie parece haber podido hacerlo sin un truco.La combinación de código que veo que usa la gente 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 se cierran (ocultan) de esta manera, eventualmente el programa falla.

¿Algunas ideas?He encontrado toneladas de publicaciones en varios foros con personas que tienen el mismo problema.Supongo que recibiré una respuesta incorrecta/incompleta aquí y mi publicación se hundirá en la nada como siempre, pero de cualquier manera, ¡gracias de antemano!

Editar 1:No puedo editar las películas SWF reales, las crea el cliente.Si no puedo cerrar ningún SWF abierto a través de Flex, ¿no es eso un problema con la arquitectura Flex?¿Mi única opción es enviar los archivos SWF al navegador web?

¿Fue útil?

Solución

...¿No es eso un problema con la arquitectura Flex?

Sí lo es, y también afecta a Flash en general.Hasta que puedas aprovechar el Cargador.unloadAndStop() método en FP10 (AIR 1.5), no puede garantizar que el contenido cargado externamente no continúe consumiendo memoria y recursos de la CPU, incluso si usa el Loader.unload() método.(Para ser honesto, no estoy 100% seguro de que ni siquiera eso garantice la liberación de recursos, pero tal vez sea pesimista).

Lo mejor que puede hacer es insistir en que los creadores del contenido que usted carga cumplan una serie de pautas, incluida la exposición de algo como un dispose() método al que su aplicación puede llamar para pedirle que libere tantos recursos como sea posible antes de que usted unload() él.Si esto no es posible, entonces es casi seguro que su aplicación aumentará el uso de memoria y CPU cada vez que cargue un archivo swf externo.Lo siento.

Si te hace sentir mejor, no estás solo.;)

Otros consejos

Es un problema que un SWF mal creado pueda hundir su aplicación, y muchos de los problemas con esto se solucionarán en Flash Player 10, como otros han mencionado.Sin embargo, independientemente de la plataforma, siempre correrá el riesgo de tener problemas si carga código de terceros; siempre existe la posibilidad de que contenga errores, pérdidas de memoria o código francamente malicioso.A menos que puedas cargar contenido en un sandbox (y no puedes hacerlo en Flash, al menos no todavía), cargar cosas malas hundirá tu aplicación, es tan simple como eso.

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 se filtran o que no se pueden descargar, porque Flash facilita hacer algo incorrecto, especialmente para cosas que viven en la línea de tiempo.Cargar cualquier contenido Flash sobre el que no tienes control directo es muy peligroso.

La mejor solución es

swfLoader.autoLoad = false;
swfLoader.unloadAndStop();
swfLoader.autoLoad = true;

De esta forma detienes el reproductor, descargas el contenido de la memoria y evitas que el sonido siga sonando.Salud

El problema reside en el archivo SWF cargado, simplemente no limpia el audio.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();                           
} 

Generalmente me mantendría alejado de SWFLoader y usaría las clases del paquete mx.modules.

Flex tiene un sistema de módulos que permite este tipo de comportamiento.Puede verificarlo aquí : http://livedocs.adobe.com/flex/3/html/help.html?content=modular_3.html .En general, cargar y descargar componentes swf dinámicamente es complicado, especialmente si esos módulos modifican algún 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 del módulo flexible, puede cargarlos y descargarlos limpiamente.

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 la GC, que son un poco desagradables porque aumentan la CPU, pero la buena noticia es que habrá 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 trucos como los que mostré arriba.

No ha mostrado todo su código, así que asumiré que no utilizó el método de descarga de la clase Loader.Además, swfLoader.load(null) me parece incorrecto ya que el método de carga espera un objeto URLRequest.Cuando quieras limpiar las cosas al final, establece el valor del objeto en nulo en lugar de llamar a una carga nula.El hecho de que aún escuche el audio indica que sus datos no se descargaron o que el archivo de audio no reside dentro del contenido que se descargó.Repasemos esto.

Ejemplo a continuación


var loader:Loader = new Loader();
var request:URLRequest = new URLRequest('test.swf');
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onSwfLoad, false, 0, true);

función onswfload (e: evento): void {addChild (loader);loader.contentLoaderInfo.addEventListener (Event.UNLOAD, onLoaderUnload, falso, 0, verdadero);

loader.contentLoaderInfo.removeEventListener (Event.COMPLETE, onSwfLoad, falso);} function onloaderUnload (e: evento): void {trace ('Loader se descargó correctamente.');} // Ahora para eliminar esto con el clic de un botón, suponiendo que el nombre de los botones sea Button_MC Button_mc.AddeventListener (MouseeVent.Mouse_Down, OnButtondown, False, 0, verdadero);

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); }

Espero que esto haya sido útil y lamento si fue redundante, pero sin ver su código no tengo forma de saber exactamente cómo abordó esto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top