2011-02-22 58 views
1

我有一个SWF,加载到非应用程序沙箱中的Adobe AIR 1.5(壳已与我们的用户安装加载的SWF,所以我不能更新到2.0版本+)。选择输入文本字段引发安全沙箱冲突于Adobe AIR

论swf的舞台是按钮,影片剪辑,动画等 - 所有这些做工精细。

当我们添加一个文本字段输入,选择该文本字段会导致安全性违规。

错误信息(在调试模式)是(我编辑的实际文件名):然后

[trace] *** Security Sandbox Violation *** 
[trace] SecurityDomain 'file:///path/to/local/loaded.swf' tried to access incompatible context 'app:/loadingApp-debug.swf' 

用户是无法输入文本TextField的。应用程序的其余部分不受影响。

的FDB堆栈跟踪只显示:

this = [Object 57216577, class='flash.utils::Timer'].Timer/tick() at <null>:0 

有没有人得到了解决类似的问题?

我猜它要么将TextField试图访问的阶段,或者一个事件试图气泡/访问全局属性。

我了解空气沙盒限制和日常使用它们 - 与sandboxBridges从父母到孩子,孩子家长等 - 也许有件事我需要公开,让这个工作?

任何线索?

编辑:

我现在已经找到了问题所在,以作为该文本字段试图做相当于

this.stage.focus = this; 

什么时候发生的MouseDown。

它似乎也无法访问加载的swfs中的KeyboardEvents,所以我想让'field'成为一个按钮,然后通过监听KeyboardEvents来控制输入的想法在水中已经死了。

现在看看是否将事件传递给通过父沙箱桥传递的回调,或者最小化的comps是否可以节省我的屁股。

回答

2

好吧,我有一个疯狂的解决方法,但它非常稳固。我将在这里几乎完整地发布它,尽管我可能会将它通用化并在某些时候将其上传到github。

在我的shell中,我有一个视图与调解器(我使用robotlegs),我打电话给EventRelayer和EventRelayerMediator。

视图的唯一目的是给舞台上的中介服务。

我暴露在使用parentSandboxBridge一些功能:

public function requestKeyboardEventRelay(eventType:String, callback:Function):void; 

public function requestMouseEventRelay(eventType:String, callback:Function):void; 

public function cancelKeyboardEventRelay(eventType:String, callback:Function):void; 

public function cancelMouseEventRelay(eventType:String, callback:Function):void; 

我的沙箱桥永远都只是转换成强类型的事件,所以这些火灾的事件,如:

RelayEvent(RelayEvent.START_RELAY_REQUESTED, KeyboardEvent, eventType, callback); 

RelayEvent(RelayEvent.CANCEL_RELAY_REQUESTED, MouseEvent, eventType, callback); 

这些由EventRelayerMediator回升并在事件图中翻译成处理程序:

override public function onRegister():void 
{   
    createRelayHandlerFactories(); 
    eventMap.mapListener(eventDispatcher, RelayEvent.START_RELAY_REQUESTED, startRelay); 
} 

protected function startRelay(e:RelayEvent):void 
{ 
    var handler:Function = createRelayHandler(e.relayEventClass, e.callback); 
    eventMap.mapListener(view.stage, e.relayEventType, handler, e.relayEventClass); 
} 

protected function createRelayHandler(relayEventClass:Class, callback:Function):Function 
{ 
    var handler:Function = relayHandlerFactoriesByEventClass[relayEventClass](callback); 

    return handler; 
    }     

protected function createRelayHandlerFactories():void 
{ 
    relayHandlerFactoriesByEventClass = new Dictionary(); 
    relayHandlerFactoriesByEventClass[KeyboardEvent] = createKeyboardEventRelayHandler; 
    relayHandlerFactoriesByEventClass[MouseEvent] = createMouseEventRelayHandler; 
}                      

protected function createKeyboardEventRelayHandler(callback:Function):Function 
{ 
    var handler:Function = function(e:KeyboardEvent):void 
    {    
     trace("Relaying from shell: " + e.toString()); 
     // passing an object because the sandbox bridge doesn't allow strong typed values, only primitives 
     var o:Object = {}; 
     o.type = e.type; 
     o.charCode = e.charCode; 
     o.keyCode = e.keyCode; 
     o.altKey = e.altKey; 
     o.ctrlKey = e.ctrlKey; 
     o.shiftKey = e.shiftKey; 
     // no point adding other props as we can't pass them 
     // to the constructor of the KeyboardEvent 
     callback(o) 
    } 

    return handler; 
} 

加载的swf传递一个只是重新组装并重新分派事件的回调。

我的输入TextField现在只是一个动态字段,它带有一个单击处理程序,它激活监听swf根上的键盘事件,然后相应地更新动态字段。

现在是超级原油,但我现在将它分解成一个强大的,经过测试的类,现在我知道它的工作原理。

我已经使用了字典来管理处理程序,因为我确信内存泄漏地狱即将跟随,我期望不得不转接FocusEvents以停止输入文本。

我需要测试内存泄漏,从parentSandboxBridge函数返回一个绑定,以便我可以确保我不会添加相同的处理程序两次等等,但是Adobe - 你会因为不会调用它并提供一个内置的在中继机制。

+0

疯狂但不错的解决方法 – 2011-02-23 09:03:51