Air for Android中已移除SWF文件音频仍后台播放问题求助
这种问题我在Flash/Air Android开发里碰到过好几次,其实核心原因是你只把SWF从舞台移除,但它的音频资源或者内部的播放逻辑还在后台跑着,没被彻底终止。给你几个具体的解决步骤:
别只移除舞台,用
unloadAndStop()彻底卸载SWF
如果你是用Loader加载的子SWF,仅仅调用removeChild(loader)或者loader.content.removeFromParent()是不够的。Air里提供了Loader.unloadAndStop()方法,它会主动停止SWF里所有的声音、动画,释放相关资源。代码示例大概是这样:// 假设loader是加载子SWF的Loader实例 loader.unloadAndStop(true); // 参数true表示强制停止所有媒体 removeChild(loader); loader = null; // 清除引用,帮助GC回收注意别用旧的
unload()方法,它不会处理音频这类资源,很容易导致残留。主动停止子SWF内的所有音频
有些子SWF里的音频可能是通过Sound类播放的,或者嵌入在MovieClip里的帧动画中。你可以在卸载前,主动遍历子SWF内容里的音频对象并停止:// 获取子SWF的根容器 var childRoot:DisplayObjectContainer = loader.content as DisplayObjectContainer; // 遍历所有子对象,停止音频 function stopAllSounds(obj:DisplayObject):void { if (obj is SoundChannel) { (obj as SoundChannel).stop(); } else if (obj is MovieClip) { (obj as MovieClip).stop(); // 停止MC的帧动画,连带里面的嵌入音频 for (var i:int = 0; i < (obj as DisplayObjectContainer).numChildren; i++) { stopAllSounds((obj as DisplayObjectContainer).getChildAt(i)); } } } stopAllSounds(childRoot);另外,如果子SWF是你自己开发的,最好在子SWF里写一个公开的停止方法,比如
public function stopAllMedia():void,父SWF直接调用这个方法,比遍历更可靠。清除所有对子SWF的引用
如果你在父SWF里还保留着对子SWF内容或者Loader的引用(比如某个全局变量、数组里的元素),Flash的垃圾回收器可能不会回收这个SWF,导致它的音频继续播放。所以卸载后一定要把相关引用设为null,比如:childSwfInstance = null; loader = null;检查子SWF的音频类型
子SWF里的音频如果设置为Event类型,它会完整播放完才停止,哪怕SWF被移除。如果是Stream类型,停止SWF播放就会中断音频。所以如果可以修改子SWF,尽量把需要随时停止的音频设为Stream类型,或者在父SWF切换时主动停止这些Event类型的音频。
内容的提问来源于stack exchange,提问作者adbury

