我有一个应用程序可以加载外部SWF文件,并通过SWFLoader Flex component在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.
如果SWF以这种方式关闭(隐藏),最终程序崩溃。
有什么想法吗?我在各种论坛上发现了很多帖子,人们遇到了同样的问题。我想我会在这里得到一个错误/不完整的答案,而且我的帖子会像往常一样陷入虚无,但不管怎样,提前谢谢!
编辑1 :我无法编辑实际的SWF电影,它们是由客户端创建的。如果我无法关闭通过Flex打开的任何SWF,那么Flex架构不是一个问题吗?我唯一的选择是将SWF发送到网络浏览器吗?
答案 0 :(得分:6)
...这不是Flex架构的问题吗?
是的,它也会影响Flash。在您可以利用FP10(AIR 1.5)中的Loader.unloadAndStop()方法之前,您无法保证外部加载的内容不会继续消耗内存和CPU资源,即使您使用Loader.unload()
方法也是如此。 (老实说,我不是百分百肯定,即使这样也可以保证释放资源,但也许我是一个悲观主义者。)
下一个最好的事情是你要坚持你加载的内容的创建者遵守一套准则,包括暴露你的应用可以调用的dispose()
方法,让它发布尽可能多的在您unload()
之前尽可能使用资源。如果这是不可能的,那么每次加载外部swf时,你的应用程序几乎肯定会在内存和cpu使用方面臃肿。抱歉。
如果它让你感觉更好,那么你并不孤单。 ;)
答案 1 :(得分:2)
这是一个问题,严重创建的SWF可能会使您的应用程序下沉,并且其中的许多问题将在其他人提到的Flash Player 10中得到修复。但是,无论平台如何,如果加载第三方代码,总是存在问题,总是存在包含错误,内存泄漏或彻头彻尾的恶意代码的可能性。除非您可以将内容加载到沙盒中(并且您不能在Flash中加载,至少现在还没有),否则加载不良内容会使您的应用程序下沉,就像那样简单。
我很遗憾地说,除非您能保证所加载内容的质量,否则您无法保证自己的应用程序的质量。 Flash开发人员因编写泄漏或无法卸载的内容而臭名昭着,因为Flash可以轻松地执行错误操作,尤其是对于生活在时间线上的内容。加载任何您无法直接控制的Flash内容是非常危险的。
答案 2 :(得分:2)
最佳解决方案是
swfLoader.autoLoad = false;
swfLoader.unloadAndStop();
swfLoader.autoLoad = true;
通过这种方式,您可以停止播放器,从内存中卸载内容并避免声音继续播放。 干杯
答案 3 :(得分:1)
问题在于加载的swf,它本身并不会清理音频。 尝试将卸载事件附加到动画片段上,如下所示:
MovieClip(event.target.content).loaderInfo.addEventListener(Event.UNLOAD, unloadMovieClipHandler);
private function unloadMovieClipHandler(event:Event) : void
{
SoundMixer.stopAll();
}
答案 4 :(得分:1)
我通常会远离SWFLoader并使用mx.modules包中的类。
Flex有一个模块系统可以实现这种行为。你可以在这里查看:http://livedocs.adobe.com/flex/3/html/help.html?content=modular_3.html。通常,动态加载和卸载swf组件是很棘手的,特别是如果这些模块修改应用程序中的任何全局状态(样式等)。但是,如果为模块创建接口,然后加载/卸载的每个类实现该接口以及扩展Flex模块类,则可以干净地加载和卸载它们。
答案 5 :(得分:0)
尝试以下方法:
try {
new LocalConnection().connect('foo');
new LocalConnection().connect('foo');
} catch (e:*) {}
这将强制执行垃圾收集例程。如果您的SWF仍然连接,那么您错过了某种连接,例如音频。
有几种方法可以强制GC,因为它们会刺激CPU,所有这些都很糟糕,但好消息是Flash Player 10中正式出现这种方式:
unloadAndStop
link:http://www.gskinner.com/blog/archives/2008/07/unloadandstop_i.html
在那之前,我担心你不得不用上面所示的黑客强迫它。
答案 6 :(得分:0)
您没有显示所有代码,因此我假设您没有使用Loader类的卸载方法。另外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);
}