Как выгрузить загруженный извне SWF-файл из компонента SWFLoader в Adobe Flex? - PullRequest
3 голосов
/ 23 сентября 2008

У меня есть приложение, которое загружает внешние SWF-файлы и воспроизводит их внутри приложения Adobe Flex / Air с помощью компонента SWFLoader Flex . Я пытался найти способ выгрузить их из события нажатия кнопки. У меня есть Google далеко и широко, и никто, кажется, не смог бы сделать это без взлома. Я вижу, что люди используют комбинацию кода:

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.

Если SWF-файлы закрыты (скрыты) таким образом, программа, в конечном итоге, вылетает.

Есть идеи? Я нашел тонны сообщений на разных форумах, где люди сталкивались с такой же проблемой. Я предполагаю, что получу один неправильный / неполный ответ здесь, и затем мой пост впадет в небытие, как обычно, но в любом случае, спасибо заранее!

Редактировать 1 : Я не могу редактировать реальные SWF-фильмы, они созданы клиентом. Если я не могу закрыть любой SWF, открытый через Flex, разве это не проблема с архитектурой Flex? Мой единственный вариант - отправлять SWF-файлы в веб-браузер?

Ответы [ 7 ]

6 голосов
/ 22 октября 2008

... разве это не проблема с архитектурой Flex?

Да, и это также влияет на Flash в целом. Пока вы не сможете использовать метод Loader.unloadAndStop () в FP10 (AIR 1.5), вы не сможете гарантировать, что внешне загруженный контент не будет продолжать использовать ресурсы памяти и процессора, даже если вы используете Loader.unload() метод. (Если честно, я не уверен на 100%, что даже это гарантирует освобождение ресурсов, но, возможно, я пессимист.)

Следующая лучшая вещь для вас - настаивать на том, чтобы создатели загружаемого вами контента придерживались ряда рекомендаций, включая предоставление чего-то вроде dispose() метода, который ваше приложение может вызвать, чтобы попросить освободить столько ресурсов, сколько возможно, прежде чем вы unload() это. Если это невозможно, то ваше приложение почти наверняка будет раздуваться в памяти и использовании процессора каждый раз, когда вы загружаете внешний SWF. Сожалею.

Если вам от этого станет лучше, вы не одиноки. ;)

2 голосов
/ 26 февраля 2013

Лучшее решение -

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

Таким образом, вы останавливаете проигрыватель, выгружаете контент из памяти и избегаете продолжения воспроизведения звука. Приветствия

2 голосов
/ 23 сентября 2008

Проблема в том, что плохо созданный SWF-файл может поглотить ваше приложение, и многие проблемы с этим будут исправлены в Flash Player 10, как уже упоминали другие. Однако независимо от платформы вы всегда рискуете столкнуться с проблемами, если загружаете сторонний код, всегда есть вероятность, что он содержит ошибки, утечки памяти или просто вредоносный код. Если вы не можете загружать контент в «песочницу» (а во Flash, по крайней мере, пока), загрузка плохих вещей может затопить ваше приложение, это так просто.

Сожалею, что если вы не можете гарантировать качество загруженного контента, вы не можете гарантировать качество своего собственного приложения. Разработчики Flash печально известны тем, что пишут вещи, которые просочились или не могут быть выгружены, потому что Flash позволяет легко делать неправильные вещи, особенно для вещей, которые живут на временной шкале. Загрузка любого содержимого Flash, которое вы не можете контролировать напрямую, очень опасна.

1 голос
/ 16 января 2009

Обычно я бы держался подальше от SWFLoader и использовал классы в пакете mx.modules.

Flex имеет модульную систему, которая обеспечивает такой тип поведения. Вы можете проверить это здесь: http://livedocs.adobe.com/flex/3/html/help.html?content=modular_3.html. В общем, динамическая загрузка и выгрузка SWF-компонентов является сложной задачей, особенно если эти модули изменяют любое глобальное состояние в приложении (стили и т. Д.). Но если вы создаете интерфейс для своих модулей, а затем каждый загружаемый / выгружаемый класс реализует этот интерфейс, а также расширяет класс flex-модулей, вы можете загружать и выгружать их без ошибок.

1 голос
/ 23 сентября 2008

Проблема заключается в загруженном SWF, он просто не очищает звук после себя. Попробуйте прикрепить событие unload к мувиклипам так:

MovieClip(event.target.content).loaderInfo.addEventListener(Event.UNLOAD, unloadMovieClipHandler);
private function unloadMovieClipHandler(event:Event) : void
{
  SoundMixer.stopAll();                           
} 
0 голосов
/ 23 сентября 2008

Вы не показали весь свой код, поэтому я предполагаю, что вы не использовали метод unload класса Loader. Также swfLoader.load (null) мне кажется неправильным, так как метод load ожидает объект URLRequest. Когда вы хотите очистить вещи в конце, установите значение объекта в null вместо вызова нулевой загрузки. Тот факт, что вы все еще слышите звук, указывает на то, что ваши данные не были выгружены или аудиофайл не находится внутри контента, который был выгружен. Пройдемся через это.

Пример ниже


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

<p>function onSwfLoad(e:Event):void
{
   addChild(loader);
   loader.contentLoaderInfo.addEventListener(Event.UNLOAD, onLoaderUnload, false, 0, true);</p>

<p>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);</p>

<p>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;
   <code>button_mc.removeEventListener(MouseEvent.MOUSE_DOWN, onButtonDown);</code>
}

Я действительно надеюсь, что это было полезно, и мне жаль, если это было излишним, но не видя ваш код, я не могу точно знать, как вы подошли к этому.
0 голосов
/ 23 сентября 2008

Попробуйте следующее:

try {
   new LocalConnection().connect('foo');
   new LocalConnection().connect('foo');
} catch (e:*) {}

Это вызовет процедуру сбора мусора. Если ваш SWF-файл все еще подключен, значит, вы пропустили какое-то соединение, например, аудио.

Есть несколько способов заставить GC, которые все отстой, потому что они нагружают процессор, но хорошая новость заключается в том, что в Flash Player 10 появится официальный путь:

unloadAndStop

ссылка: http://www.gskinner.com/blog/archives/2008/07/unloadandstop_i.html

До тех пор, боюсь, вам придется взломать его взломами, как я показал выше.

...