Как мне выгрузить загруженный извне SWF-файл из компонента SWFLoader в Adobe Flex?

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

Вопрос

У меня есть приложение, которое загружает внешние SWF-файлы и воспроизводит их внутри приложения Adobe Flex / Air через Гибкий компонент SWFLoader.Я пытался найти способ выгрузить их из события нажатия кнопки.Я использую 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?Является ли мой единственный вариант отправкой SWFS-файлов в веб-браузер?

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

Лучшим решением является

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

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

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

MovieClip(event.target.content).loaderInfo.addEventListener(Event.UNLOAD, unloadMovieClipHandler);
private function unloadMovieClipHandler(event:Event) : void
{
  SoundMixer.stopAll();                           
} 

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

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

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

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

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

Вы показали не весь свой код, поэтому я предполагаю, что вы не использовали метод 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);

функция onSwfLoad(e:Событие): недействительна { addChild(загрузчик);loader.contentLoaderInfo.addEventListener(Событие.ВЫГРУЗКА, onLoaderUnload, false, 0, true);

loader.contentLoaderInfo.removeEventListener(событие.ЗАВЕРШЕНО, onSwfLoad, false);} функция onLoaderUnload (e: событие): недействительна { трассировка('ЗАГРУЗЧИК БЫЛ УСПЕШНО ВЫГРУЖЕН.');} //Теперь, чтобы удалить это нажатием кнопки, предположим, что имя кнопки - button_mc button_mc.addEventListener(MouseEvent.MOUSE_DOWN, onButtonDown, 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); }

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top