2012-08-22 73 views
0

鍊金術的大部分構建都是靜態的swc構建。這些對於直接鏈接庫是很好的,但如果你一次嘗試使用多個庫,你通常會(總是)遇到共享內存空間的問題。我讀過的一個解決方案是構建swf,並將它們動態加載到自己的ApplicationDomain中。這將爲所有庫提供自己的內存,並允許您加載多個Alchemy庫。 (正如在adobe論壇上的這些主題中提到的:http://forums.adobe.com/message/3665801http://forums.adobe.com/message/3927791我怎樣才能加載一個adobe鍊金術swf動態編譯

我的問題是:如何加載這些swf並獲取其中的代碼?似乎沒有關於此問題的任何文檔,雖然我知道如何加載swf,但我不知道如何訪問代碼,因爲我沒有與swf的任何接口。

回答

0

問題是,我們想要動態加載Alchemy庫,但是如果我們將庫構建爲SWF,它將無法工作(因爲這使獨立的應用程序)。但是我們不能動態加載SWC--或者我們可以嗎?

這裏是做什麼(假設名爲mylib庫):

  1. 構建mylib爲SWC。
  2. 解壓縮mylib.swc並提取library.swf文件;其重命名爲mylib.swf
  3. 嵌入mylib.swfbinary asset
  4. 在運行時,實例化資源爲ByteArray
  5. 而資產ByteArrayLoader#loadBytes
  6. 當裝載觸發完成後,使用Loader#contentLoaderInfo獲得的該ApplicationDomain中加載SWF
  7. 使用ApplicationDomain#getDefinition查找Alchemy初始值設定項類。例如,cmodule.mylib.CLibInit
  8. 使用像你這樣的初始化器normally would。例如,致電init等。
  9. ...利潤!

您可以用這種方法嵌入任意數量的Alchemy庫,每個庫都運行在它自己的ApplicationDomain中。

+0

謝謝,送我正確的方向。 –

0

我一直在嘗試通過創建一個新的ApplicationDomain並將其傳遞給加載器的上下文來動態加載庫。我做錯了什麼是存儲對該ApplicationDomain的引用,並嘗試從該引用獲取定義。由於某些原因返回null。通過實現paleozogt的答案並修改了動態加載swf的結果,我最終得到了正確的代碼,該代碼不使用ApplicationDomain的存儲引用,而是從加載器的contentLoaderInfo中獲取它。

下面的代碼,如果你想動態加載庫:

package 
{ 
    import flash.display.Loader; 
    import flash.events.Event; 
    import flash.net.URLRequest; 
    import flash.system.ApplicationDomain; 
    import flash.system.LoaderContext; 

    public class AlchemyDynamicLoad 
    { 
     private var _library:Object; 
     private var _loader:Loader; 

     public function AlchemyDynamicLoad() 
     { 
      var loaderContext:LoaderContext = new LoaderContext(false, new ApplicationDomain()); 
      var request:URLRequest = new URLRequest("../assets/mylib.swf"); 
      _loader = new Loader(); 
      _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler); 
      _loader.load(request, loaderContext); 
     } 

     private function completeHandler(event:Event):void 
     { 
      // NOTE: Storing a reference to the application domain you feed to the loaderContext and then trying to get the 
      // definition from that reference is not going to work for some reason. You have to get the applicationDomain 
      // from the contentLoaderInfo, otherwise getDefinition returns null. 
      var libClass:Class = Class(_loader.contentLoaderInfo.applicationDomain.getDefinition("cmodule.mylib.CLibInit")); 
      _library = new libClass().init(); 
     } 
    }   
} 

而這裏的代碼,如果你想將它嵌入(paleozogt的答案):

package 
{ 
    import flash.display.Loader; 
    import flash.events.Event; 

    public class AlchemyStaticLoad 
    { 
     [Embed(source="../assets/mylib.swf", mimeType="application/octet-stream")] 
     private static var _libraryClass:Class; 

     private var _library:Object; 
     private var _loader:Loader; 

     public function AlchemyStaticLoad() 
     { 
      _loader = new Loader(); 
      _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler); 
      _loader.loadBytes(new _libraryClass()); 
     } 

     private function completeHandler(event:Event):void 
     { 
      var libClass:Class = Class(_loader.contentLoaderInfo.applicationDomain.getDefinition("cmodule.mylib.CLibInit")); 
      _library = new libClass().init(); 
     } 
    } 
}