Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache flex Flex 4 AIR APP卸载模块的正确方式_Apache Flex_Module - Fatal编程技术网

Apache flex Flex 4 AIR APP卸载模块的正确方式

Apache flex Flex 4 AIR APP卸载模块的正确方式,apache-flex,module,Apache Flex,Module,我在谷歌上到处寻找这个问题,但我找不到一个好的答案。 我正在使用Flex4并使用模块构建一个air应用程序(因为这是一个大项目,所以会有很多模块)。 我设法在popupmanager调用的titlewindow中加载模块,但是当titlewindow关闭时,模块没有卸载(垃圾)——我使用flasbuilder中的探查器检查了这一点 这是我的代码,我需要知道我是否在正确的方向上使用模块,然后才能在项目中做更多的工作 多谢大家 Main APP: MXML <s:WindowedApplic

我在谷歌上到处寻找这个问题,但我找不到一个好的答案。 我正在使用Flex4并使用模块构建一个air应用程序(因为这是一个大项目,所以会有很多模块)。 我设法在popupmanager调用的titlewindow中加载模块,但是当titlewindow关闭时,模块没有卸载(垃圾)——我使用flasbuilder中的探查器检查了这一点

这是我的代码,我需要知道我是否在正确的方向上使用模块,然后才能在项目中做更多的工作

多谢大家

Main APP: MXML

<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   xmlns:tblusersservice="services.tblusersservice.*"
                   xmlns:valueObjects="valueObjects.*"
                   xmlns:tbluserservice="services.tbluserservice.*"
                   width="100%" height="100%" applicationComplete="checkForUpdate()" preinitialize="nativeWindow.maximize();" currentState="login">

<fx:Script source="includes/_loadtracker.as"/>



<s:Panel id="panelmain" includeIn="mainmenu" left="5" width="100%" height="100%" resizeEffect="Resize" title="Main menu">

    <s:Image id="companymenu" right="15" top="130" width="118" height="93" buttonMode="true"
             click="loadmodule('mod_company', 'Company Information', 931, 446);" source="assets/company.png" useHandCursor="true"/>


</s:Panel>



</s:WindowedApplication>




_loadtracker.as:

// ActionScript file
import flash.filesystem.*;
import flash.events.ErrorEvent;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.*;
import air.update.ApplicationUpdaterUI;
import air.update.events.UpdateEvent;
import mx.controls.Alert;       
import mx.managers.PopUpManager;
import mx.rpc.events.ResultEvent;
import spark.components.TitleWindow;
import valueObjects.*;
import flash.desktop.NativeApplication;



// Open the pop-up window.
private function loadmodule(modname:String, modtitle:String, modwidth:int, modheight:int):void {
// Create a non-modal TitleWindow container.
settings.moduletoload = modname;
var titleWindow:TitleWindow=
    PopUpManager.createPopUp(this, showmodules, true) as TitleWindow;
titleWindow.title = modtitle;
titleWindow.width = modwidth;
titleWindow.height = modheight + 35;
    PopUpManager.centerPopUp(titleWindow);
}





showmodules.mxml

<s:TitleWindow xmlns:fx="http://ns.adobe.com/mxml/2009" 
           xmlns:s="library://ns.adobe.com/flex/spark" 
           xmlns:mx="library://ns.adobe.com/flex/mx" width="400" height="400"  creationComplete="initModule()" close="handleCloseEvent()">

<fx:Script>
    <![CDATA[

        import mx.controls.Alert;
        import mx.core.IVisualElement;
        import mx.events.ModuleEvent;
        import mx.managers.PopUpManager;
        import mx.modules.IModuleInfo;
        import mx.modules.ModuleManager;
        import mx.rpc.events.ResultEvent;
        import services.tbluserservice.*;

        public var info:IModuleInfo;
        public var modclosed:Boolean = false;

        private function initModule():void {
            this.addEventListener("foobar", handleCloseEventmodule);

            info = ModuleManager.getModule("/modules/"+settings.moduletoload+".swf");
            info.addEventListener(ModuleEvent.READY, modEventHandler);           

            info.load(null, null, null, moduleFactory);
        }

        /* Add an instance of the module's class to the display list. */        
        private function modEventHandler(e:ModuleEvent):void {

            this.addElement(info.factory.create() as IVisualElement);
        }

        // Handle the close button and Cancel button.
        public function handleCloseEvent():void {

                PopUpManager.removePopUp(this);
                info.unload();
                info.release();
                info = null;

        }

    ]]>
</fx:Script>

<fx:Declarations>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
</s:TitleWindow>




mod_company.mxml

<s:Module xmlns:fx="http://ns.adobe.com/mxml/2009"
      xmlns:s="library://ns.adobe.com/flex/spark"
      xmlns:mx="library://ns.adobe.com/flex/mx"
      xmlns:tblcompanyservice="services.tblcompanyservice.*"
      xmlns:valueObjects="valueObjects.*"
      width="931" height="446"
      creationComplete="LoadData()">
<fx:Script>
    <![CDATA[
        import mx.events.FlexEvent;

        protected function dataGrid_creationCompleteHandler(event:FlexEvent):void
        {
            getAllTblcompanyResult.token = tblcompanyService.getAllTblcompany();
        }

    ]]>
</fx:Script>

<fx:Script source="../includes/_company.as"/>

<fx:Declarations>
    <tblcompanyservice:TblcompanyService id="tblcompanyService"
                                         fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"
                                         showBusyCursor="true"/>
    <s:CallResponder id="getTblcompanyByIDResult" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"
                     result="tblcompany = getTblcompanyByIDResult.lastResult as Tblcompany"/>
    <valueObjects:Tblcompany id="tblcompany"/>
    <s:CallResponder id="updateTblcompanyResult"/>
    <s:CallResponder id="getAllTblcompanyResult"/>
    <!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Label x="81" y="41" text="COMPANY NAME"/>
<s:Label x="81" y="71" text="ADDRESS"/>
<s:Label x="83" y="131" text="CITY"/>
<s:Label x="83" y="161" text="STATE"/>
<s:Label x="83" y="191" text="ZIP"/>
<s:Label x="83" y="221" text="COUNTRY"/>
<s:Label x="582" y="41" text="TELEPHONE"/>
<s:Label x="582" y="71" text="FAX"/>
<s:Label x="582" y="102" text="WATTS"/>
<s:Label x="83" y="276" text="OWNER"/>
<s:Label x="83" y="324" text="LOGO PATH"/>
<s:TextInput id="fNameTextInput" x="185" y="32" width="323" text="{tblcompany.fName}"/>
<s:TextInput id="faddressTextInput" x="185" y="62" width="256" text="{tblcompany.faddress}"/>
<s:TextInput id="faddress2TextInput" x="185" y="92" width="256" text="{tblcompany.faddress2}"/>
<s:TextInput id="fcityTextInput" x="185" y="122" width="256" text="{tblcompany.fcity}" textAlign="left"/>
<s:TextInput id="fstateTextInput" x="185" y="152" width="256" text="{tblcompany.fstate}"/>
<s:TextInput id="fzipTextInput" x="185" y="182" width="81" text="{tblcompany.fzip}"/>
<s:TextInput id="fcountryTextInput" x="185" y="212" width="256" text="{tblcompany.fcountry}"/>
<s:TextInput id="ftelTextInput" x="701" y="32" text="{tblcompany.ftel}"/>
<s:TextInput id="ffaxTextInput" x="701" y="62" text="{tblcompany.ffax}"/>
<s:TextInput id="fwattsTextInput" x="701" y="92" text="{tblcompany.fwatts}"/>
<s:TextInput id="fownerTextInput" x="185" y="266" width="418" text="{tblcompany.fowner}"/>
<s:TextInput id="flogopathTextInput" x="185" y="314" width="644" text="{tblcompany.flogopath}"/>
<s:TextInput id="fidTextInput" x="224" y="379" text="{tblcompany.fid}" visible="false"/>
<s:Button id="button" x="79" y="379" label="Save" click="button_clickHandler(event)"/>
<s:DataGrid id="dataGrid" x="158" y="242"
            creationComplete="dataGrid_creationCompleteHandler(event)" requestedRowCount="4">
    <s:columns>
        <s:ArrayList>
            <s:GridColumn dataField="fid" headerText="fid"></s:GridColumn>
            <s:GridColumn dataField="fName" headerText="fName"></s:GridColumn>
            <s:GridColumn dataField="fowner" headerText="fowner"></s:GridColumn>
            <s:GridColumn dataField="faddress" headerText="faddress"></s:GridColumn>
            <s:GridColumn dataField="faddress2" headerText="faddress2"></s:GridColumn>
            <s:GridColumn dataField="fcity" headerText="fcity"></s:GridColumn>
            <s:GridColumn dataField="fzip" headerText="fzip"></s:GridColumn>
            <s:GridColumn dataField="fstate" headerText="fstate"></s:GridColumn>
            <s:GridColumn dataField="fcountry" headerText="fcountry"></s:GridColumn>
            <s:GridColumn dataField="ftel" headerText="ftel"></s:GridColumn>
            <s:GridColumn dataField="ffax" headerText="ffax"></s:GridColumn>
            <s:GridColumn dataField="fwatts" headerText="fwatts"></s:GridColumn>
            <s:GridColumn dataField="flogopath" headerText="flogopath"></s:GridColumn>
            <s:GridColumn dataField="femail" headerText="femail"></s:GridColumn>
        </s:ArrayList>
    </s:columns>
    <s:typicalItem>
        <fx:Object faddress="faddress1" faddress2="faddress21" fcity="fcity1"
                   fcountry="fcountry1" femail="femail1" ffax="ffax1" fid="fid1"
                   flogopath="flogopath1" fName="fName1" fowner="fowner1" fstate="fstate1"
                   ftel="ftel1" fwatts="fwatts1" fzip="fzip1"></fx:Object>
    </s:typicalItem>
    <s:AsyncListView list="{getAllTblcompanyResult.lastResult}"/>
</s:DataGrid>
</s:Module>




_company.as


// ActionScript file
//import flash.desktop.NativeApplication;
import flash.events.MouseEvent;
import flash.events.Event;
import mx.controls.Alert;
//import mx.core.Application;
//import mx.core.mx_internal;
import services.tblcompanyservice.*;
import valueObjects.*;

protected function LoadData():void {
getTblcompanyByIDResult.token = tblcompanyService.getTblcompanyByID(parseInt("1"));
}

protected function button_clickHandler(event:MouseEvent):void {
tblcompany.fid = parseInt(fidTextInput.text);

tblcompany.fName = fNameTextInput.text;
tblcompany.fowner = fownerTextInput.text;
tblcompany.faddress = faddressTextInput.text;
tblcompany.faddress2 = faddress2TextInput.text;
tblcompany.fcity = fcityTextInput.text;
tblcompany.fzip = fzipTextInput.text;
tblcompany.fstate = fstateTextInput.text;
tblcompany.fcountry = fcountryTextInput.text;
tblcompany.ftel = ftelTextInput.text;
tblcompany.ffax = ffaxTextInput.text;
tblcompany.fwatts = fwattsTextInput.text;
tblcompany.flogopath = flogopathTextInput.text;
tblcompany.femail = "";
updateTblcompanyResult.token = tblcompanyService.updateTblcompany(tblcompany);
//Alert.show("Modifications saved");
//this.dispatchEvent(new Event("foobar", true));
}
Main应用程序:MXML
_loadtracker.as:
//动作脚本文件
导入flash.filesystem.*;
导入flash.events.ErrorEvent;
导入flash.events.MouseEvent;
导入flash.events.Event;
导入flash.display.*;
导入air.update.ApplicationUpdateUI;
导入air.update.events.UpdateEvent;
导入mx.controls.Alert;
导入mx.managers.PopUpManager;
导入mx.rpc.events.ResultEvent;
导入spark.components.TitleWindow;
导入有价值的对象。*;
导入flash.desktop.NativeApplication;
//打开弹出窗口。
私有函数loadmodule(modname:String,modtitle:String,modwidth:int,modheight:int):void{
//创建非模态标题窗口容器。
settings.moduletoload=modname;
变量titleWindow:titleWindow=
createPopUp(这个,showmodules,true)作为TitleWindow;
titleWindow.title=modtitle;
titleWindow.width=modwidth;
titleWindow.height=modheight+35;
PopUpManager.centerPopUp(标题窗口);
}
showmodules.mxml

卸载Flex模块已经完成。Flex 4和我认为4.5已经开始着手解决基本问题,使我们的生活更轻松

当主应用程序中的某个东西维护对模块中某个对象的引用时,它将阻止模块卸载。有很多方法可以做到这一点。由于Flex的工作方式,它仍然可能导致一些问题。但是主要的麻烦已经缓解了(不过我会确保您使用的是Flex4.5)

你现在考虑这件事绝对是明智的。不是关于是否使用模块的选择,而是确保它们正在卸载

我链接到的这篇文章是一位FlexSDK开发人员的老文章,虽然其中一些问题可能已经不存在了,但这些概念应该会有所启发

编辑

在进一步的回顾中,我发现只有一件事值得一看:

  • 模块中的脚本标记可能存在与样式可能引入的问题相同的问题(也可能是转移注意力的问题)。其思想是,使用此脚本的第一个类可以通过Flex与脚本在内部永久关联。如果该类是一个模块,它将永远不会卸载。作为测试,您也可以尝试在
    WindowedApplication
    类中声明脚本标记(即使它没有被使用)

我考虑的另一件事是在您的视图中绑定变量。但是在进一步的检查中,我看不出这些是如何导致内存泄漏的。

我认为问题在于每次都在创建一个新的TitleWindow,而TitleWindow会向通过模块加载程序加载的模块添加一个事件侦听器,并对其进行修改。理论上,PopupManager.removePopup每次都应该取消对TitleWindow的引用,但是,老实说,将此功能作为全局/静态类编写的人可能无法相信在其他地方坚持良好的实践,因此,您可能应该使用F3查看PopupManager上的代码,确保它删除了它添加的所有事件侦听器,并将对标题窗口的引用置零。由于它是一个静态类,一旦有东西与它对话,如果它不能正确地解除引用,它们将在应用程序的生命周期中一直存在

接下来,您将手动创建模块的实例,即使已经加载了一个实例。您做了一些事情(除了删除事件侦听器)来尝试释放加载程序,但从未释放手动创建的实例。为了简化一些事情,尝试只添加加载的模块,而不是创建一个额外的模块

另一个建议是不要使用视图元素代替数据存储。因此,当您获取VO时,不必绑定到VO,而是从它填充字段。当有任何变化时,根据VO的值更新VO。这会产生更多的代码,但首先,您总是知道您的数据是最新的。另一方面,如果需要,数据可以独立于视图进行传输。但这可以帮助您消除绑定将VO保存在内存中的可能性

还有一些事情会在代码周围产生一种淡淡的谷仓气味,这些也可能是问题的根源。例如,你的标题窗口子类似乎有一个对设置的引用,即使你没有给它一个。这表明设置实际上是一个静态类,您忽略了类应该以大写开头的命名约定。更重要的是,如果您在后台通道中进行了这样的通信,则无法查看您的代码并确定您在某种程度上为设置提供了对它所持有的内容的引用的情况下没有进行任何操作

您还有一个似乎未声明的变量modulefactory,但我认为这可能是一个名称不正确的类,它与TitleWindow位于同一个包中(因此没有import语句)。快速建议:如果你想在论坛上获得帮助,遵循命名约定将使想要帮助你的人更容易了解你所做的事情。在这种情况下,可能会有一些地方您有“非法”功能,避开了最佳实践OOP通信,并且由于您命名事物的方式,它们不容易识别

但最终,我认为如果您只使用模块的一个副本并删除事件侦听器,那么您应该