0

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

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

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

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

嗯,在我的代码中似乎越来越不像一个错误,而更像是播放器中的一个错误(在所有情况下都是 10.0.45.2)......至少 id 喜欢在它冻结的时候看到调用堆栈。有没有什么方法可以做到这一点而不需要他们安装各种零碎的东西,例如让闪存写出一个 log.txt 或带有“跟踪”之类的功能,我可以在相关代码中插入?

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

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

particles.push(p);

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

getQualifiedClassName(p) = ::Particle
getQualifiedClassName(particles) = __AS3__.vec::Vector.<::Particle>

任何想法为什么这是一个问题以及如何使它工作?

编辑4:

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

也许它是一个 Flash 错误,或者我错过了关于不在向量中使用内部类或其他东西的备忘录,尽管如果是这种情况,我会期望某些东西或其他东西(无论是在编译时还是在调试运行时)明确地禁止它,例如一些“私有 var 粒子:Vector.<Particle>;”上的错误 线。如果我有机会,我想我会考虑联系 Adob​​e Flash 团队来解决这个问题。

感谢您提供调试提示的帮助,我猜这些提示更符合原始问题:)

4

2 回答 2

2

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

不管是什么问题,我都有一些可以帮助您调试的东西。一个在 SWF 中创建伪跟踪窗口的类,比 javascript 的 extinterface 好得多。我忘记是谁写的了,但我觉得它是 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;
        }
    }
}
于 2010-06-08T18:40:03.153 回答
1

根据冻结发生的时间来判断,尝试找出可能有问题的代码的一些可能性,并使用De MonsterDebugger检查变量等。

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

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

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

于 2010-06-07T15:50:27.563 回答