加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Flex ModuleLoader组件导致内存泄漏.如何正确卸载模块?

发布时间:2020-12-15 01:45:35 所属栏目:百科 来源:网络整理
导读:该应用程序太大而无法在此描述,但我可以告诉您,我有多达20个模块或更多客户端可以随时使用.如果我继续在屏幕后加载屏幕,我的应用程序可以达到500MB甚至更多. 我用来加载和卸载模块的脚本是: public function createModule(modulo:String):void { if(moduleL
该应用程序太大而无法在此描述,但我可以告诉您,我有多达20个模块或更多客户端可以随时使用.如果我继续在屏幕后加载屏幕,我的应用程序可以达到500MB甚至更多.

我用来加载和卸载模块的脚本是:

public function createModule(modulo:String):void {
                if(moduleLoader != null){
                    moduleLoader.unloadModule();
                    //moduleLoader.url = null;
                    moduleLoader.url = "com/oss/facturable/components/" + modulo + "?version=" + model.configXML.versionApp;    
                    moduleLoader.loadModule();
                }       
            }
            private function errorHandler(e:ModuleEvent):void {
                Alert.show("No se ha podido cargar el modulo. Contacte al departamento técnico.");
            }

加载模块的Container:

<s:BorderContainer width="98%" height="98%" includeIn="mainState" styleName="bcModuleLoader" top="100">
                    <s:layout>
                        <s:HorizontalLayout paddingLeft="10" paddingRight="10" paddingTop="10" paddingBottom="10"/>
                    </s:layout>
                    <s:Scroller width="100%" height="100%">
                        <s:Group>
                            <mx:ModuleLoader id="moduleLoader" error="errorHandler(event)" width="100%" height="100%" horizontalAlign="center" verticalAlign="top" creationComplete="createModule('bandejaEntrada.swf')"/>              
                        </s:Group>
                    </s:Scroller>
 </s:BorderContainer>

每当我点击我认为与此处发布无关的菜单选项时,都会调用createModule函数.总而言之,这就是我现在所做的一切,使其发挥作用和泄漏:S

这是官方的unloadModule函数,我想,从它的外观来看,内存应该很好地分配这个东西,我的意思是,看!它删除所有eventListeners和子对象.为什么我的内存在卸载时保持不变,并在打开新模块时在其上加载更多内存?! Augh!

public function unloadModule():void
    {
        if (child)
        {
            removeChild(child);
            child = null;
        }

        if (module)
        {
            module.removeEventListener(ModuleEvent.PROGRESS,moduleProgressHandler);
            module.removeEventListener(ModuleEvent.SETUP,moduleSetupHandler);
            module.removeEventListener(ModuleEvent.READY,moduleReadyHandler);
            module.removeEventListener(ModuleEvent.ERROR,moduleErrorHandler);

            module.unload();
            module.removeEventListener(ModuleEvent.UNLOAD,moduleUnloadHandler);
            module = null;
        }
    }

解决方法

从 this article开始:

将HierachicalData与AdvancedDataGrid一起使用时,控件会使用IHierarchicalCollectionView接口跟踪分层和分组数据.该接口具有openNodes属性,该属性包含一个对象Array,这些对象表示当前在AdvancedDataGrid中打开的数据提供程序的节点.

如果使用新数据提供程序替换数据提供程序,则AdvancedDataGrid控件不会清除openNodes属性.由于openNodes属性包含对旧数据提供程序中对象的引用,因此无法通过垃圾回收从内存中删除对象.要确保可以从内存中删除旧数据提供程序,请在替换数据提供程序时使用事件处理程序清除openNodes属性.

将事件侦听器添加到数据提供程序的CollectionEvent.COLLECTION_CHANGE事件以清除openNodes属性.

// Handle the colectionChange event.
private function removeOpenNodes(event:CollectionEvent):void 
{
  if(event.kind == CollectionEventKind.RESET)
    IHierarchicalCollectionView(adg.dataProvider).openNodes = {};
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读