调试仅发布闪存问题

时间:2010-06-07 15:24:09

标签: actionscript-3 flash debugging flex flash-builder

我有一个Adobe Flash 10程序在某些情况下冻结,但只有在Flash播放器的发布版本下运行时才会冻结。使用调试版本,应用程序可以正常工作。

调试此类问题的最佳方法是什么?我考虑在我的计算机上安装发布播放器并尝试设置某种非图形化的输出方法(我想有一些方法来编写日志文件或类似的?),但我认为没有办法同时发布和无论如何安装的调试版本:(。

编辑:好的,我设法用发行版替换了我的flash播放器版本,没有冻结......所以我目前所知道的是:

Flash:     Debug   Release
Vista 32:  works   works
XP PRO 32: works*  freeze
  • 我给了他们我必须测试的调试播放器

嗯,似乎越来越不像我的代码中的错误,更像是播放器中的错​​误(在所有情况下都是10.0.45.2)...至少id喜欢看到它冻结的点上的callstack。是否有某种方法可以做到这一点,而无需他们安装各种零碎,例如通过让flash写出一个log.txt或类似“跟踪”的函数,我可以插入相关代码中吗?

EDIT2:我刚把swf给了另一个使用XP 32bit的人,结果相同:(

EDIT3: 好的,通过大量使用flash.external.ExternalInterface.call(“alert”,“......”);我设法找到导致问题的确切行(我还改进了异常处理代码,而不是冻结它告诉我有一个“未处理”的异常)。现在的问题是,在某些机器上发布播放器本身就会出现问题......

particles.push(p);

在所述平台上导致TypeError#1034。粒子是Vector。< Particle>,p是粒子。我用getQualifiedClassName测试并得到:

  

getQualifiedClassName(p)= ::粒子
  getQualifiedClassName(particles)= __AS3 __。vec :: Vector。< :: Particle>

为什么这是一个问题以及如何使其发挥作用的任何想法?

EDIT4:

好的,我好像已经解决了这个问题。 Particle类只是一个简单的内部类,位于使用它的动作脚本文件中的包{...}之后。我把它移到了自己的文件(particle.as)中,并在我的包中成为一个合适的公共类,问题就解决了。

也许它是一个flash bug或者我错过了关于不在向量或其他东西中使用内部类的备忘录,尽管如果是这样的话我会期望某些东西或其他(在编译时或使用调试运行时)来明确地禁止它,例如“private var particles:Vector。< Particle&gt ;;”上的一些错误线。如果我有机会,我想我会联系Adobe Flash团队,了解这个或那个。

感谢您提供帮助,提供调试技巧,我想更多的是原始问题行:)

2 个答案:

答案 0 :(得分:2)

这是一个很长的镜头,但是粒子是你点击的对象吗?如果是这样,那么在错误的冒泡阶段捕获事件,并推送event.target(假设它是一个粒子)可能会导致该问题。

无论出现什么问题,我都有一些可以帮助你调试的东西。一个在SWF中创建伪跟踪窗口的类,比远程接口到javascript要好得多。我忘了是谁写的,但我觉得它是Senocular。每次我需要从最终用户那里获取回溯时,我都会使用它。

将其放入项目的默认包中,调用stage.addChild(new Output());,然后跟踪调用Output.trace(“A message”);

package {
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.display.Stage;
    import flash.display.GradientType;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Matrix;
    import flash.text.TextField;
    import flash.text.TextFieldType;
    import flash.text.TextFormat;
    import flash.text.TextFormatAlign;
    import flash.text.TextFieldAutoSize;

    /**
     * Creates a pseudo Output panel in a publish
     * swf for displaying trace statements.
     * For the output panel to capture trace 
     * statements, you must use Output.trace()
     * and add an instance to the stage:
     * stage.addChild(new Output());
     *
     */
    public class Output extends Sprite {
        private var output_txt:TextField;
        private var titleBar:Sprite;
        private static var instance:Output;
        private static var autoExpand:Boolean = false;
        private static var maxLength:int = 1000;

        public function Output(outputHeight:uint = 400){
            if (instance && instance.parent){
                instance.parent.removeChild(this);
            }

            instance = this;
            addChild(newOutputField(outputHeight));
            addChild(newTitleBar());

            addEventListener(Event.ADDED, added);
            addEventListener(Event.REMOVED, removed);
        }

        // public methods
        public static function trace(str:*):void {
            if (!instance) return;
            instance.output_txt.appendText(str+"\n");
            if (instance.output_txt.length > maxLength) {
                instance.output_txt.text = instance.output_txt.text.slice(-maxLength);
            }
            instance.output_txt.scrollV = instance.output_txt.maxScrollV;
            if (autoExpand && !instance.output_txt.visible) instance.toggleCollapse();
        }

        public static function clear():void {
            if (!instance) return;
            instance.output_txt.text = "";
        }

        private function newOutputField(outputHeight:uint):TextField {
            output_txt = new TextField();
            //output_txt.type = TextFieldType.INPUT;
            output_txt.border = true;
            output_txt.borderColor = 0;
            output_txt.background = true;
            output_txt.backgroundColor = 0xFFFFFF;
            output_txt.height = outputHeight;
            var format:TextFormat = output_txt.getTextFormat();
            format.font = "_sans";
            output_txt.setTextFormat(format);
            output_txt.defaultTextFormat = format;
            return output_txt;
        }

        private function newTitleBar():Sprite {
            var barGraphics:Shape = new Shape();
            barGraphics.name = "bar";
            var colors:Array = new Array(0xE0E0F0, 0xB0C0D0, 0xE0E0F0);
            var alphas:Array = new Array(1, 1, 1);
            var ratios:Array = new Array(0, 50, 255);
            var gradientMatrix:Matrix = new Matrix();
            gradientMatrix.createGradientBox(18, 18, Math.PI/2, 0, 0);
            barGraphics.graphics.lineStyle(0);
            barGraphics.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, gradientMatrix);
            barGraphics.graphics.drawRect(0, 0, 18, 18);

            var barLabel:TextField = new TextField();
            barLabel.autoSize = TextFieldAutoSize.LEFT;
            barLabel.selectable = false;
            barLabel.text = "Output";
            var format:TextFormat = barLabel.getTextFormat();
            format.font = "_sans";
            barLabel.setTextFormat(format);

            titleBar = new Sprite();
            titleBar.addChild(barGraphics);
            titleBar.addChild(barLabel);
            return titleBar;
        }

        // Event handlers
        private function added(evt:Event):void {
            stage.addEventListener(Event.RESIZE, fitToStage);
            titleBar.addEventListener(MouseEvent.CLICK, toggleCollapse);
            fitToStage();
            toggleCollapse();
        }

        private function removed(evt:Event):void {
            stage.removeEventListener(Event.RESIZE, fitToStage);
            titleBar.removeEventListener(MouseEvent.CLICK, toggleCollapse);
        }

        private function toggleCollapse(evt:Event = null):void {
            if (!instance) return;
            output_txt.visible = !output_txt.visible;
            fitToStage(evt);
        }

        private function fitToStage(evt:Event = null):void {
            if (!stage) return;
            output_txt.width = stage.stageWidth;
            output_txt.y = stage.stageHeight - output_txt.height;
            titleBar.y = (output_txt.visible) ? output_txt.y - titleBar.height : stage.stageHeight - titleBar.height;
            titleBar.getChildByName("bar").width = stage.stageWidth;
        }
    }
}

答案 1 :(得分:1)

判断冻结何时发生,尝试查明违规代码的可能性,并使用De MonsterDebugger检查变量等。

修改 我很确定实际的调用堆栈只能在Flash Player / AIR的调试版本中使用。尽管如此,在调试播放器中从按钮的处理程序中跟踪堆栈以查看是否有任何不合适的地方可能很有用:

var err:Error = new Error(“An Error”);
trace(err.getStackTrace());

仅供参考,getStackTrace方法仅在调试播放器中可用,因此无法将其写入生产中的log.txt。