Глобальный ловец ошибок и неуловимый loaderInfo
Не секрет, что с версии плеера 10.1 появилась возможность глобального отлова ошибок.
Но есть одно но!
Отлавливать ошибки может только loaderInfo документ класса, который, как оказалось, не равен stage.loaderInfo и не всегда root.loaderInfo.
Хотя stage.loaderInfo.parameters и т.п. читаются и совпадают.
Для 2-кадровой флэшки, где документ классом был класс прелоадера - пришлось передавать этот самый loaderInfo в класс главного приложения:
private function startUp():void { var mainClass:Class = getDefinitionByName(_mainClassName) as Class; var main:DisplayObject = new mainClass(); main["documentClassLoaderInfo"] = loaderInfo; stage.addChild(main); }
Второй момент:
Отлов этого события всё-равно в дебаговом плеере не запрещен - появляется окошко с ошибкой и кнопками продолжить. Это бесит, а иногда просто не хватает реакции человека, чтобы нажать эту кнопку, ну и логика подразумевает некие тайминги.. Да и просто бесит)
Сидишь ютуб смотришь, а на тебя какая-то куча ошибок сыпется) Да - в дебаговом плеере смотреть ютуб нерепрезентативно. Но мне лень переключаться.
Ребята (разработчики вк, ютуба и прочих) - ловите ошибки у себя в логерах. Не давайте повод посмеяться другим разрабам: мол - вот блин - весь вк плеер сыпется еррорами, а мы чем хуже...
Решение (подсмотрено в org.as3commons.logging):
if ( _documentClassLoaderInfo.uncaughtErrorEvents){ _documentClassLoaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler); } .... private function uncaughtErrorHandler(event:UncaughtErrorEvent):void { event.preventDefault(); ....
UPD:
Выяснил когда происходит это неожиданное поведение.
root становится равным stage и не равным руту документ класса
если мы в Preloader будем делать
а не
Т.е. для любых объектов добавленных напрямую на stage - root не равен документ классу, а равен stage.
На этом точно всё.
Всего комментариев 10
Комментарии
10.10.2012 01:08 | |
Коротко и по делу. Спасибо.
|
10.10.2012 01:09 | |
На это "коротко" убил почти целый рабочий день)
Ну чтобы понять, что documentClassLoaderInfo != stage/root.loaderInfo |
|
Обновил(-а) Котяра 11.10.2012 в 02:51
|
10.10.2012 06:25 | |
Цитата:
documentClassLoader != stage/root.loaderInfo
|
10.10.2012 13:23 | |
Дима, каюсь для однокадровой флэшки не проверял.
но в классе, который создаётся прелдоадером в addedToStageHandler имеем следующее: trace("stage.loaderInfo == _documentClassLoaderInfo :" , (stage.loaderInfo == _documentClassLoaderInfo)); trace("root.loaderInfo == stage.loaderInfo :" , (root.loaderInfo == stage.loaderInfo)); trace("root.loaderInfo == _documentClassLoaderInfo :" , (root.loaderInfo == _documentClassLoaderInfo)); stage.loaderInfo == _documentClassLoaderInfo : false root.loaderInfo == stage.loaderInfo : true root.loaderInfo == _documentClassLoaderInfo : false Т.е. факт что не всегда: Цитата:
Фактически существует один LoaderInfo на файл.
|
|
Обновил(-а) Котяра 10.10.2012 в 17:50
|
10.10.2012 18:53 | |
Ничего не понимаю.. Собрал в FD тестовую флэшку на основе темплейта с Preloader.
package { import flash.display.DisplayObject; import flash.display.LoaderInfo; import flash.display.MovieClip; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.ProgressEvent; import flash.utils.getDefinitionByName; public class Preloader extends MovieClip { public function Preloader() { if (stage) { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; } addEventListener(Event.ENTER_FRAME, checkFrame); loaderInfo.addEventListener(ProgressEvent.PROGRESS, progress); loaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioError); // TODO show loader } private function ioError(e:IOErrorEvent):void { trace(e.text); } private function progress(e:ProgressEvent):void { // TODO update loader } private function checkFrame(e:Event):void { if (currentFrame == totalFrames) { stop(); loadingFinished(); } } private function loadingFinished():void { removeEventListener(Event.ENTER_FRAME, checkFrame); loaderInfo.removeEventListener(ProgressEvent.PROGRESS, progress); loaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, ioError); // TODO hide loader startup(); } private function startup():void { var _documentClassLoaderInfo:LoaderInfo = this.loaderInfo; trace("---------------In preloader----------------"); trace("stage.loaderInfo == _documentClassLoaderInfo :", (stage.loaderInfo == _documentClassLoaderInfo)); trace("root.loaderInfo == stage.loaderInfo :", (root.loaderInfo == stage.loaderInfo)); trace("root.loaderInfo == _documentClassLoaderInfo :", (root.loaderInfo == _documentClassLoaderInfo)); var mainClass:Class = getDefinitionByName("Main") as Class; var main:DisplayObject = new mainClass(); main["documentClassLoaderInfo"] = _documentClassLoaderInfo; addChild(main); } } } package { import flash.display.LoaderInfo; import flash.display.Sprite; import flash.events.Event; [Frame(factoryClass="Preloader")] public class Main extends Sprite { private var _documentClassLoaderInfo:LoaderInfo; public function Main():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); trace("---------------In Main----------------"); trace("stage.loaderInfo == _documentClassLoaderInfo :", (stage.loaderInfo == _documentClassLoaderInfo)); trace("root.loaderInfo == stage.loaderInfo :", (root.loaderInfo == stage.loaderInfo)); trace("root.loaderInfo == _documentClassLoaderInfo :", (root.loaderInfo == _documentClassLoaderInfo)); } public function set documentClassLoaderInfo(value:LoaderInfo):void { _documentClassLoaderInfo = value; } } } Цитата:
---------------In preloader----------------
stage.loaderInfo == _documentClassLoaderInfo : false root.loaderInfo == stage.loaderInfo : false root.loaderInfo == _documentClassLoaderInfo : true ---------------In Main---------------- stage.loaderInfo == _documentClassLoaderInfo : false root.loaderInfo == stage.loaderInfo : false root.loaderInfo == _documentClassLoaderInfo : true Буду копать. |
|
Обновил(-а) Котяра 10.10.2012 в 19:06
|
10.10.2012 19:44 | |
Я понял разницу.
Если главный класс размещать внутри прелоадера, то будет ожидаемое поведение. private function startup():void { var _documentClassLoaderInfo:LoaderInfo = this.loaderInfo; var mainClass:Class = getDefinitionByName("Main") as Class; var main:DisplayObject = new mainClass(); main["documentClassLoaderInfo"] = _documentClassLoaderInfo; addChild(main); } private function startup():void { var _documentClassLoaderInfo:LoaderInfo = this.loaderInfo; var mainClass:Class = getDefinitionByName("Main") as Class; var main:DisplayObject = new mainClass(); main["documentClassLoaderInfo"] = _documentClassLoaderInfo; stage.addChild(main); // вот он - камень преткновенья } Цитата:
---------------In preloader----------------
stage.loaderInfo == _documentClassLoaderInfo : false root.loaderInfo == stage.loaderInfo : false root.loaderInfo == _documentClassLoaderInfo : true ---------------In Main---------------- stage.loaderInfo == _documentClassLoaderInfo : false root.loaderInfo == stage.loaderInfo : true root.loaderInfo == _documentClassLoaderInfo : false |
|
Обновил(-а) Котяра 11.10.2012 в 00:50
|
11.10.2012 23:50 | |
Судя по
Код:
---------------In Main---------------- stage.loaderInfo == _documentClassLoaderInfo : false root.loaderInfo == stage.loaderInfo : true root.loaderInfo == _documentClassLoaderInfo : false Запутал ты меня, Костя. Я не зря приводил пример со спрайтом. Куда ты добавил сиротливый Main? Там у него и root, ведущий к файлу-документклассу или к Stage, если его добавили на него. Разберем построчно. Код:
stage.loaderInfo === _documentClassLoaderInfo : false Код:
root.loaderInfo === stage.loaderInfo : true Цитата:
root.loaderInfo == _documentClassLoaderInfo : false
Код:
stage.loaderInfo == _documentClassLoaderInfo : false |
|
Обновил(-а) dimarik 12.10.2012 в 00:08
|
Последние записи от Котяра
- Страх и ненависть в Нью-Дели или сборка мультипака для arm7 и x86 c Adobe AIR 14 в FB (16.06.2014)
- Нативный EventDispatcher в старлинге (27.11.2013)
- Нужны ошибки компиляции при создании экземпляра синглетона извне? Запросто! (13.09.2013)
- ARP - новый формат упаковки ресурсов (07.02.2013)
- DropShadowFilter и GlowFilter в Starling (16.01.2013)