Ошибка приведения типа при приведении объекта, загруженного в другой домен приложения

В настоящее время мое приложение содержит несколько виджетов, которыми управляет менеджер виджетов. Когда пользователь щелкает виджет (например, вспомогательный виджет), диспетчер виджетов загружает виджет в отдельный домен родственного приложения со следующей строкой кода:

wgtInfo.load(null, null, null, moduleFactory); //wgtInfo = IModuleInfo

Однако позже я не могу использовать переменные и функции виджета. Я пытаюсь найти вспомогательный виджет в списке виджетов диспетчера виджетов, и мне это удается. Но когда я пытаюсь преобразовать виджет Helper из типа IBaseWidget (интерфейс, который используется всеми виджетами) в тип HelperWidget, я получаю следующую ошибку:

TypeError: Ошибка № 1034: Ошибка приведения типа.....

Это связано с тем, что домен приложения класса, пытающегося использовать вспомогательный виджет, отличается от домена приложения вспомогательного виджета. Я попытался исправить это, загрузив все виджеты в тот же домен приложения, что и загрузчик:

wgtInfo.load(ApplicationDomain.currentDomain, null, null, moduleFactory);

Теперь я получаю следующую ошибку всякий раз, когда пытаюсь загрузить виджет Helper:

TypeError: Ошибка № 1009: невозможно получить доступ к свойству или методу нулевой ссылки на объект.

Как я могу загрузить свой вспомогательный виджет в общий домен приложения, доступный для других виджетов?


person Kyle    schedule 28.04.2011    source источник
comment
Я немного смущен здесь. Но есть предположение, что ошибка связана не с ApplicationDomain, а с тем, какие классы вы компилируете в какой модуль. Flex автоматически оптимизирует неиспользуемые классы из SWF; но вы можете принудительно вернуть их в аргумент компилятора include-libraries.   -  person JeffryHouser    schedule 28.04.2011


Ответы (3)


Я считаю, что ваша проблема связана с тем, что класс не включен в swf. Это связано с тем, что Flash не компилирует классы в SWF, если они не используются для уменьшения размера файла. Чтобы предотвратить это, вам нужно всего лишь создать переменную с нужным вспомогательным классом в этом классе, например:

private var helper:HelperWidget;

Посмотрите, поможет ли это.

person J_A_X    schedule 28.04.2011
comment
Я использовал тот же подход (см. мой комментарий к исходному вопросу), но вместо создания неиспользуемой переменной я рекомендовал использовать аргумент компилятора include-libraries. - person JeffryHouser; 28.04.2011
comment
@www.Flextras.com, да, это тоже работает, но хреново поддерживать, если у вас их много. - person J_A_X; 28.04.2011
comment
Я не знаю, почему подход с аргументом компилятора сложнее поддерживать, чем подход с «фальшивой переменной». - person JeffryHouser; 28.04.2011
comment
@www.Flextras.com, если у вас есть централизованный способ компиляции вашего приложения Flex (например, maven), тогда отлично, но я видел разных людей с разными IDE, и если вы установите его в Flash Builder, он не будет распространяться . Таким образом, несмотря ни на что, это сработает. - person J_A_X; 28.04.2011
comment
Спасибо за предложение. Я пробовал это раньше, безрезультатно. Смотрите мой комментарий ниже для решения, которое я обнаружил. - person Kyle; 03.05.2011

Я собираюсь опубликовать свой «комментарий» как реальный ответ. Я предполагаю, что ошибка связана не с ApplicationDomain, а с тем, какие классы вы компилируете в свой модуль. Когда Flex компилирует SWF, он автоматически оптимизирует неиспользуемые классы из SWF. Вы можете заставить их вернуться в SWF одним из двух способов:

  1. Используйте аргумент компилятора include-libraries, чтобы компилятор Flex, чтобы добавить класс в ваш SWF.
  2. Добавьте фальшивую переменную в свое приложение, чтобы компилятор Flex подумал, что она используется, и добавил ее в окончательный SWF. Что-то вроде этого.

    частная переменная myFakeObject : HelperWidth;

person JeffryHouser    schedule 28.04.2011

После безуспешных попыток использовать ряд решений (включая другие ответы на этой странице) я прибегнул к другому решению, основанному на событиях.

В итоге я отправил пользовательское событие, чтобы уведомить другие мои виджеты, когда виджет Helper завершил загрузку:

(HelperWidget.mxml)

ViewerContainer.addEventListener(AppEvent.WIDGET_OPEN_TAB, widgetOpenTabHandler); //listen for other widgets to open a tab within the Helper Widget
ViewerContainer.dispatchEvent(new AppEvent(AppEvent.WIDGET_READY_OPEN_TAB)); //notify other widgets that loading is complete

Другие мои виджеты прослушивают срабатывание этого события и после завершения отправляют другое событие (AppEvent.WIDGET_OPEN_TAB) для выполнения функции внутри вспомогательного виджета.

person Kyle    schedule 03.05.2011