LoaderContext и ApplicationDomain изменяются с помощью Adobe AIR? - PullRequest
8 голосов
/ 03 марта 2009

В настоящее время я экспериментирую с загрузкой внешних SWF-файлов как из стандартного приложения AS3, так и из приложения AIR. Кажется, что приложение AIR работает не так, как стандартный SWF-файл, запускаемый Flash Player.

Согласно документации , свойство applicationDomain LoaderContext также можно использовать в приложении AIR, но, похоже, оно не работает.

У меня есть следующий код:

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"));
        }
    }
}

Компиляция этого кода в виде SWF-файла и запуск его с помощью Flash Player приводит к следующему выводу:

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

Но тот же код, что и в приложении AIR, производит другой вывод:

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

Согласно документации, первый вывод (с использованием SWF с Flash Player, а не приложения AIR) является правильным. Кроме того, игра с этим фрагментом и изменение домена приложения на другие возможные конфигурации (например, new ApplicationDomain(null) или ApplicationDomain.currentDomain) в точности соответствуют тому, что говорится в документации с SWF, но не изменяют вывод приложения AIR. *

Любая подсказка, почему AIR просто игнорирует домен приложения, переданный в контекст загрузчика? Есть документация по этой конкретной проблеме?

Большое спасибо.

Ответы [ 2 ]

14 голосов
/ 03 марта 2009

Понял.

Проблема была вызвана другим поведением в системе SecurityDomain в приложении AIR. Когда SWF-файл загружается в приложение AIR, он всегда зависит от другой изолированной программной среды. Таким образом, AIR создает новый SecurityDomain для этого SWF.

Поскольку SecurityDomain - это группа из одного или нескольких ApplicationDomain с, это поведение вынудило создать новый ApplicationDomain (внутри нового SecurityDomain), игнорируя указанный (принадлежащий главная 'SecurityDomain).

Существует обходной путь использования URLLoader. При загрузке из байт-кода (с использованием Loader.loadBytes) SWF-файл загружается в тот же SecurityDomain. Вот почему вы должны установить allowLoadBytesCodeExecution в true, поскольку это может быть небезопасно. Поэтому косвенная загрузка SWF-файла сначала с помощью URLLoader, а затем с помощью Loader.loadBytes решает эту проблему.

Вот фрагмент:

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"));
        }
    }
}

Надеюсь, это поможет.

1 голос
/ 09 января 2013

это хорошо, спасибо:)

Еще одна деталь: allowLoadBytesCodeExecution теперь является устаревшим свойством, оно было определено в AIR 1.0. Из AIR 2.0 вместо этого используйте allowCodeImport .

чао, PG

...