2009-03-03 31 views
8

Tôi hiện đang thử nghiệm tải các tệp SWF bên ngoài từ cả ứng dụng AS3 tiêu chuẩn và ứng dụng AIR. Dường như ứng dụng AIR không hoạt động giống như một SWF chuẩn do Flash Player thực hiện.LoaderContext và ApplicationDomain thay đổi với Adobe AIR?

Theo số documentation, thuộc tính applicationDomain của LoaderContext cũng có thể sử dụng được trong ứng dụng AIR, nhưng có vẻ như nó không hoạt động.

Tôi có đoạn mã sau:

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

    public class Invoker extends Sprite 
    { 
     private var _ldr : Loader; 

     public function Invoker() 
     { 
      _ldr = new Loader(); 
      _ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onChildOneComplete); 

      var ldrC : LoaderContext = new LoaderContext(false, 
       new ApplicationDomain(ApplicationDomain.currentDomain) 
      ); 

      _ldr.load(new URLRequest("otherSwf.swf"), ldrC); 
     } 

     private function onChildOneComplete(e : Event) : void 
     { 
      var c1ad : ApplicationDomain = (e.target as LoaderInfo).applicationDomain; 
      var inad : ApplicationDomain = ApplicationDomain.currentDomain; 

      trace("Child One parentDomain : " + c1ad.parentDomain); 
      trace("Invoker parentDomain : " + inad.parentDomain); 

      trace("Child One has Invoker : " + c1ad.hasDefinition("Invoker")); 
      trace("Invoker has Invoker : " + inad.hasDefinition("Invoker")); 
     } 
    } 
} 

Biên dịch mã này như là một tập tin SWF và khởi chạy nó với Flash Player làm sản lượng này, mà dường như ngay:

Child One parentDomain : [object ApplicationDomain] 
Invoker parentDomain : null 
Child One has Invoker : true 
Invoker has Invoker : true 

Nhưng cùng mã dưới dạng ứng dụng AIR có đầu ra khác nhau:

Child One parentDomain : null 
Invoker parentDomain : null 
Child One has Invoker : false 
Invoker has Invoker : true 

Theo tài liệu n, đầu ra đầu tiên (sử dụng SWF với Flash Player, chứ không phải ứng dụng AIR) là đúng. Ngoài ra, chơi xung quanh với đoạn mã này và thay đổi miền ứng dụng sang các cấu hình có thể khác (như new ApplicationDomain(null) hoặc ApplicationDomain.currentDomain) thực hiện những gì tài liệu nói với SWF, nhưng không thay đổi đầu ra của ứng dụng AIR.

Bất kỳ đầu mối nào tại sao AIR đơn giản bỏ qua miền ứng dụng được chuyển đến ngữ cảnh của trình tải? Bất kỳ tài liệu nào về vấn đề cụ thể này?

Cảm ơn bạn rất nhiều.

Trả lời

14

OK.

Sự cố xảy ra do một hành vi khác trong hệ thống SecurityDomain trong ứng dụng AIR. Khi một tệp SWF được tải trong một ứng dụng AIR, nó luôn phụ thuộc vào một sandbox khác. Do đó, AIR tạo một SecurityDomain mới cho SWF này.

Từ một SecurityDomain là một nhóm gồm một hoặc nhiều ApplicationDomain s, hành vi này buộc phải tạo ra một mới ApplicationDomain (trong mới SecurityDomain), bỏ qua một trong những quy định (trong đó thuộc về 'chính' SecurityDomain).

Có một giải pháp thay thế bằng cách sử dụng URLLoader. Khi được tải từ bytecode (sử dụng Loader.loadBytes), một SWF được tải trong cùng một SecurityDomain. Đây là lý do tại sao bạn phải đặt allowLoadBytesCodeExecution thành true vì nó có thể không an toàn. Vì vậy, tải SWF gián tiếp, đầu tiên mặc dù một URLLoader, và sau đó với Loader.loadBytes, giải quyết vấn đề này.

Sau đây là đoạn:

package { 
    import flash.display.Loader; 
    import flash.display.LoaderInfo; 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.net.URLLoader; 
    import flash.net.URLLoaderDataFormat; 
    import flash.net.URLRequest; 
    import flash.system.ApplicationDomain; 
    import flash.system.LoaderContext; 
    import flash.utils.ByteArray; 

    public class Invoker extends Sprite 
    { 
     public function Invoker() 
     { 
      var uldr : URLLoader = new URLLoader(); 
      uldr.dataFormat = URLLoaderDataFormat.BINARY; 
      uldr.addEventListener(Event.COMPLETE, onBytesComplete); 

      uldr.load(new URLRequest("otherSwf.swf")); 
     } 

     private function onBytesComplete(e : Event) : void 
     { 
      var bytes : ByteArray = (e.target as URLLoader).data; 

      var ldr : Loader = new Loader(); 
      ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onChildComplete); 

      var ldrC : LoaderContext = new LoaderContext(); 

      // This property was for AIR 1.0. 
      //ldrC.allowLoadBytesCodeExecution = true; 

      // Since AIR 2.0, it's allowCodeImport. 
      ldrC.allowCodeImport = true; 

      ldr.loadBytes(bytes, ldrC); 
     } 

     private function onChildComplete(e : Event) : void 
     { 
      var c1ad : ApplicationDomain = (e.target as LoaderInfo).applicationDomain; 
      var inad : ApplicationDomain = ApplicationDomain.currentDomain; 

      trace("Child One parentDomain : " + c1ad.parentDomain); 
      trace("Invoker parentDomain : " + inad.parentDomain); 

      trace("Child One has Invoker : " + c1ad.hasDefinition("Invoker")); 
      trace("Invoker has Invoker : " + inad.hasDefinition("Invoker")); 
     } 
    } 
} 

Hope this helps.

+0

Lưu ý rằng bạn sẽ cần phải sử dụng [allowCodeImport] như đã nói bởi @pigiuz –

+0

Tôi đã chỉnh sửa câu trả lời của tôi để thực hiện việc này vào tài khoản. Cảm ơn! – Tyn

1

đó là một trong những tốt, thanx :)

Chỉ cần thêm một chi tiết: allowLoadBytesCodeExecution bây giờ là một tài sản di sản, nó được định nghĩa trong AIR 1.0. Từ AIR 2.0 khi sử dụng allowCodeImport thay thế.

ciao, PG

Các vấn đề liên quan