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

时间:2020-03-06 14:34:05  来源:igfitidea点击:

我有一个加载外部SWF文件并通过SWFLoader Flex组件在Adobe Flex / Air应用程序中播放它们的应用程序。我一直试图找到一种方法来将它们从按钮单击事件中卸载。我已经遍及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电影,它们是由客户端创建的。如果我无法关闭通过Flex打开的任何SWF,那么Flex体系结构不是问题吗?我唯一的选择是将SWF文件发送到Web浏览器吗?

解决方案

问题出在加载的SWF文件上,它根本不会清除音频。
尝试将卸载事件添加到如下的动画片段上:

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

链接:http://www.gskinner.com/blog/archives/2008/07/unloadandstop_i.html

在此之前,恐怕我们将不得不像上面显示的那样通过黑客强制使用它。

我们尚未显示所有代码,因此我将假定我们未使用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中得到解决,就像其他人提到的那样。但是,无论使用哪种平台,如果我们加载第三方代码,都将始终有遇到问题的风险,它总是有可能包含错误,内存泄漏或者恶意代码。除非我们可以将内容加载到沙箱中(并且至少不能在Flash中加载),否则加载不良内容会使应用程序崩溃,就这么简单。

很遗憾地说,除非我们可以保证所加载内容的质量,否则就不能保证自己的应用程序的质量。 Flash开发人员以编写泄漏或者无法卸载的内容而臭名昭著,因为Flash可以很容易地做错事情,尤其是对于时间线上的事情。直接加载任何我们无法控制的Flash内容非常危险。

... isn't that a problem with the Flex architecture?

是的,它通常还会影响Flash。除非可以利用FP10(AIR 1.5)中的Loader.unloadAndStop()方法,否则即使我们使用`Loader.unload(),也不能保证外部加载的内容不会继续消耗内存和CPU资源。方法。 (说实话,我不是100%肯定会保证释放资源,但我可能是悲观主义者。)

其次,我们最好坚持所加载内容的创建者遵循一系列准则,包括公开诸如dispose()之类的方法,应用可以调用该方法以要求其释放尽可能多的资源。在unload()之前。如果这不可能,那么每次加载外部swf时,应用程序几乎肯定会在内存和cpu使用上膨胀。对不起。

如果能让我们感觉更好,那么我们并不孤单。 ;)

我通常会远离SWFLoader并使用mx.modules包中的类。

Flex具有启用此类行为的模块系统。我们可以在这里查看:http://livedocs.adobe.com/flex/3/html/help.html?content=modular_3.html。通常,动态加载和卸载swf组件非常棘手,特别是如果那些模块修改了应用程序中的任何全局状态(样式等)。但是,如果为模块创建接口,然后加载/卸载的每个类都实现该接口并扩展flex模块类,则可以干净地加载和卸载它们。