Apache flex 如何从Adobe Flex中的SWFLoader组件卸载外部加载的SWF文件?

Apache flex 如何从Adobe Flex中的SWFLoader组件卸载外部加载的SWF文件?,apache-flex,air,adobe,swfloader,Apache Flex,Air,Adobe,Swfloader,我有一个应用程序,可以加载外部SWF文件,并通过在Adobe Flex/Air应用程序中播放这些文件。我一直在试图找到一种方法从按钮点击事件中卸载它们。我用谷歌搜索了很多地方,似乎没有人能不经过黑客的攻击就做到这一点。我看到人们使用的代码组合是: swfLoader.source = ""; // Removes the external link to the SWF. swfLoader.load(null); // Forces the loader to try to load noth

我有一个应用程序,可以加载外部SWF文件,并通过在Adobe Flex/Air应用程序中播放这些文件。我一直在试图找到一种方法从按钮点击事件中卸载它们。我用谷歌搜索了很多地方,似乎没有人能不经过黑客的攻击就做到这一点。我看到人们使用的代码组合是:

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.
如果主权财富基金以这种方式关闭(隐藏),最终程序将崩溃

有什么想法吗?我在不同的论坛上发现了大量有同样问题的帖子。我想我会在这里得到一个错误/不完整的答案,然后我的帖子会像往常一样变成一片空白,但不管怎样,提前谢谢


编辑1:我无法编辑实际的SWF电影,它们是由客户端创建的。如果我不能关闭任何通过Flex打开的SWF,这不是Flex架构的问题吗?将swf发送到web浏览器是我唯一的选择吗?

问题在于加载的swf,它本身不会清理音频。 尝试将卸载事件附加到movieclips上,如下所示:

MovieClip(event.target.content).loaderInfo.addEventListener(Event.UNLOAD, unloadMovieClipHandler);
private function unloadMovieClipHandler(event:Event) : void
{
  SoundMixer.stopAll();                           
} 
请尝试以下操作:

try {
   new LocalConnection().connect('foo');
   new LocalConnection().connect('foo');
} catch (e:*) {}
这将强制执行垃圾收集例程。如果您的SWF仍然连接,那么您错过了某种连接,比如音频

有两种方法可以强制GC,它们都很糟糕,因为它们会占用CPU,但好消息是Flash Player 10中出现了一种官方方法:

unloadAndStop
链接:


在那之前,我担心您将不得不像我上面所展示的那样使用黑客来强制它。

您没有展示所有代码,因此我假设您没有使用Loader类的unload方法。另外,swfLoader.load(null)对我来说似乎是错误的,因为load方法需要一个URLRequest对象。当您希望在最后清理时,将对象的值设置为null,而不是调用null加载。您仍能听到音频这一事实表明您的数据未卸载,或者音频文件未驻留在卸载的内容中。让我们来看看这个

下面的例子

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

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

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

我真的希望这是有帮助的,如果它是多余的,我很抱歉,但是没有看到您的代码,我无法确切地知道您是如何做到这一点的。

这是一个问题,创建不好的SWF会使您的应用程序陷入困境,正如其他人所提到的那样,与此相关的许多问题将在Flash Player 10中得到解决。然而,无论平台如何,如果您加载第三方代码,您都会面临出现问题的风险,它总是可能包含bug、内存泄漏或彻头彻尾的恶意代码。除非你能将内容加载到沙盒中(你不能在Flash中加载,至少现在还不能),否则加载不好的东西会让你的应用程序陷入困境,就这么简单

很抱歉,除非你能保证加载内容的质量,否则你不能保证你自己应用程序的质量。Flash开发人员因编写泄漏或无法卸载的东西而臭名昭著,因为Flash使得做错事变得容易,尤其是那些生活在时间线上的东西。加载任何你无法直接控制的Flash内容是非常危险的

。。。这不是Flex架构的问题吗

是的,一般来说,它也会影响Flash。除非您能够利用FP10(AIR 1.5)中的方法,否则无法保证外部加载的内容不会继续消耗内存和cpu资源,即使您使用
Loader.unload()
方法。(老实说,我不能100%肯定即使这样也能保证资源的释放,但也许我是个悲观主义者。)

下一个最好的方法是坚持你加载的内容的创建者遵守一套准则,包括公开类似
dispose()
方法的内容,你的应用程序可以调用该方法,要求它在你
unload()
加载之前释放尽可能多的资源。如果这是不可能的,那么您的应用程序几乎肯定会在每次加载外部swf时内存和cpu使用量膨胀。对不起


如果这能让你感觉好一点,你并不孤单

我通常不使用SWFLoader,而是使用mx.modules包中的类

Flex有一个支持这种行为的模块系统。您可以在这里查看:。通常,动态加载和卸载swf组件是很棘手的,尤其是当这些模块修改应用程序中的任何全局状态(样式等)时。但是,如果您为模块创建了一个接口,然后加载/卸载的每个类都实现了该接口并扩展了flex模块类,那么您可以干净地加载和卸载它们

最好的解决方案是

swfLoader.autoLoad = false;
swfLoader.unloadAndStop();
swfLoader.autoLoad = true;
通过这种方式,您可以停止播放机,从内存中卸载内容,并避免声音继续播放。。
干杯

我没有使用加载器,我使用的是Flex SWFLoader组件。不过,明天早上我会试试加载器课。谢谢…对我来说,GC黑客似乎不是最好的做法。我只建议在开发环境中使用它来帮助获得更有意义的内存使用值。在生产中依赖它可能会让你以后后悔。编辑:似乎是Flash9的一个bug。希望现在可以修复:在Loader.unloadAndStop()无法工作后,dactual找到了这篇文章。看不到希望了!古怪的你能详细说明一下吗?如果一个还不存在,甚至可以问一个问题!