7 Replies Latest reply on Jun 14, 2013 10:31 AM by flexchief

    Flex two-phase preloader - problem preloading AIR

    www.marcelvanduijn.com

      Hi all,

       

      I ran into a problem preloading a Flex AIR project. I guess a lot of you are familiar with the 2-phase preloading prinicple of Flex. You defer dispatching FlexEvent.INIT_COMPLETE and Event.COMPLETE to a moment thats suits you. I can get this to work fine with regular Flex projects, but when using this preloading technique with a Flex AIR project I get the following error:

       

      TypeError: Error #1009: Cannot access a property or method of a null object reference. at mx.core::WindowedApplication/enterFrameHandler()[C:\autobuild\3.5.0\frameworks\projects\a irframework\src\mx\core\WindowedApplication.as:2526]

       

      This happens because WindowedApplication.creationCompleteHandler adds an enterFrameHandler:

       

          private function creationCompleteHandler(event:Event):void
          {
              addEventListener(Event.ENTER_FRAME, enterFrameHandler);
              _nativeWindow = systemManager.stage.nativeWindow;
          }

       

      and WindowedApplication.ennterFrameHandler tries to access the stage:

       

            private function enterFrameHandler(e:Event):void
          {
              removeEventListener(Event.ENTER_FRAME, enterFrameHandler);

              // If nativeApplication.nativeApplication.exit() has been called,
              // the window will already be closed.
              if (stage.nativeWindow.closed)
                  return;

       

      The red line of code throws the error mentioned above (its line 2526 of WindowedApplication) Because the preloader defers dispatching FlexEvent.INIT_COMPLETE and Event.COMPLETE the main application is not yet on the stage!

       

      The only way I can get the 2-phase Flex preloading working for preloading a Flex AIR application is not to defer the dispatching of the events. But I need to defer them to apply some animation to the preloader (fade-out).

       

      Are there any known solutions for this problem? Any help is greatly appreciated!

       

      Thanks,

       

      Marcel

        • 1. Re: Flex two-phase preloader - problem preloading AIR
          Flex harUI Adobe Employee

          That bug will be fixed in 3.6.  I think you can add your own high priority

          handler and stopImmediatePropagation on the event.

          • 2. Re: Flex two-phase preloader - problem preloading AIR
            www.marcelvanduijn.com Level 1

            Hi,

             

            thanks for getting back. So it's a bug?

             

            I've been looking into your suggestion and that doesnt seem to do the trick either, or maybe I didnt understand you correct . When I catch FlexEvent.CREATION_COMPLETE and prevent it from reaching WindowedApplication the initiation cycle stops and the application never gets initiated. Then the preloader never receives the FlexEvent.INIT_COMPLETE event, and cannot fade-out and dispatch the final Event.COMPLETE.

             

            Was this process what you meant? I cant imagine proper preloading of Flex AIR isnt possible.

             

            Can you explain a bit more, and/or maybe know of bugfixes?

            • 3. Re: Flex two-phase preloader - problem preloading AIR
              Flex harUI Adobe Employee

              Here's the bug: https://bugs.adobe.com/jira/browse/SDK-25373

               

              I wouldn't catch CREATION_COMPLETE, I would catch the ENTER_FRAME going to

              the app, test if stage == null and call stopImmediatePropagation if it is.

              • 4. Re: Flex two-phase preloader - problem preloading AIR
                www.marcelvanduijn.com Level 1

                Hi,

                 

                ok thanks a lot for your help. I got it to work. Flagged the answer as correct to score you some points

                 

                For anyone reading this thread, here's what you need todo for implementation of the workaround:

                 


                1. In your IPreloaderDisplay instance (custom or extender of DownloadProgressBar) add property

                 

                     private var pendingWindowedApplicationEnterFrameEvent:Event;

                 

                2. in your FlexEvent.INIT_PROGRESS handler add

                 

                            if (Application.application != null) {
                                Application.application.addEventListener(Event.ENTER_FRAME, onWindowedApplicationEnterFrame, false, int.MAX_VALUE);
                                Application.application.addEventListener(Event.ADDED_TO_STAGE, onWindowedApplicationAddedToStage, false, int.MAX_VALUE);
                                trace("SCREEN: ", Application.application.screen);
                            }

                 

                3.  write your WindowedApplication enter-frame handler

                 

                        /*
                        @handler onWindowedApplicationEnterFrame
                        */
                        private function onWindowedApplicationEnterFrame(e:Event):void {
                           
                            // defer event
                            pendingWindowedApplicationEnterFrameEvent = e.clone();
                            e.stopImmediatePropagation();
                           
                        }

                 

                4. Write your WindowedApplication added-to-stage handler

                 

                        /*
                        @handler onWindowedApplicationAddedToStage
                        */
                        private function onWindowedApplicationAddedToStage(e:Event):void {
                           
                            // remove listeners
                            Application.application.addEventListener(Event.ADDED_TO_STAGE, onWindowedApplicationAddedToStage, false);
                            Application.application.removeEventListener(Event.ENTER_FRAME, onWindowedApplicationEnterFrame, false);
                           
                            // dispatch pending enter frame event
                            dispatchEvent(pendingWindowedApplicationEnterFrameEvent);
                           
                        }

                 

                Now defering dispatching Event.COMPLETE in preloading a Flex AIR project works fine.

                • 5. Re: Flex two-phase preloader - problem preloading AIR
                  Flex harUI Adobe Employee

                  Thanks for the points.  I think you could have skipped the added to stage

                  handler and simply tested if stage != null in the enterFrame handler and

                  removed the enterframe listener if true.

                  • 6. Re: Flex two-phase preloader - problem preloading AIR
                    www.marcelvanduijn.com Level 1

                    Hi,

                     

                    yeah, you're right. Added-to-stage isnt really necessary. Maybe I'll leave it out. Though esthetically I like the added-to-stage handler as well

                     

                    Anyway, the problem is solved. Once again thanks.

                    • 7. Re: Flex two-phase preloader - problem preloading AIR
                      flexchief

                      Brilliant thanks a lot man works like a charm!