3

我有一个加载外部 SWF 文件并通过SWFLoader Flex 组件在 Adob​​e Flex/Air 应用程序中播放它们的应用程序。我一直在尝试找到一种从按钮单击事件中卸载它们的方法。我在 Google 上搜索的范围很广,似乎没有人能够在没有 hack 的情况下做到这一点。我看到人们使用的代码组合是:

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 浏览器吗?

4

7 回答 7

6

... 这不是 Flex 架构的问题吗?

是的,而且它通常也会影响 Flash。在您可以利用 FP10 (AIR 1.5) 中的Loader.unloadAndStop()方法之前,您无法保证外部加载的内容不会继续消耗内存和 cpu 资源,即使您使用该Loader.unload()方法也是如此。(老实说,我不能 100% 确定即使这样也能保证资源的释放,但也许我是个悲观主义者。)

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

如果它让你感觉更好,你并不孤单。;)

于 2008-10-22T04:00:36.930 回答
2

这是一个问题,即创建不当的 SWF 会使您的应用程序陷入困境,正如其他人所提到的,许多与此相关的问题将在 Flash Player 10 中得到解决。但是,无论在哪个平台上,如果您加载第三方代码,您总是会遇到问题,它总是有可能包含错误、内存泄漏或彻头彻尾的恶意代码。除非您可以将内容加载到沙箱中(并且您不能在 Flash 中,至少现在还不能),否则加载不好的东西会使您的应用程序陷入困境,就这么简单。

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

于 2008-09-23T07:02:36.333 回答
2

最好的解决方案是

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

通过这种方式,您可以停止播放器,从内存中卸载内容并避免声音继续播放.. 干杯

于 2013-02-26T18:30:48.930 回答
1

问题在于加载的 swf,它本身并没有清理音频。尝试像这样将卸载事件附加到影片剪辑上:

MovieClip(event.target.content).loaderInfo.addEventListener(Event.UNLOAD, unloadMovieClipHandler);
private function unloadMovieClipHandler(event:Event) : void
{
  SoundMixer.stopAll();                           
} 
于 2008-09-22T22:32:30.817 回答
1

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

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

于 2009-01-15T23:39:53.447 回答
0

尝试以下操作:

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

在那之前,恐怕你将不得不像我上面展示的那样用黑客来强迫它。

于 2008-09-23T00:43:29.100 回答
0

您还没有显示所有代码,所以我假设您没有使用 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); }

我确实希望这会有所帮助,如果它是多余的,我很抱歉,但是如果没有看到您的代码,我无法确切知道您是如何处理这个问题的。

于 2008-09-23T01:32:28.000 回答