I have a very simple Flex application for mobile phones which uses 3 tabs (with the TabbedViewNavigatorApplication).
It seems that everytime I switch tabs, the selected view is reloaded.
I've set a creationComplete command to do something and everytime I click on the tab it executes the function.
Isn't it possible for the views to get loaded 1 time and that's it?
Seems to me that this behaviour is exactly the point on mobile devices since you want to keep memory / cpu usage as low as possible.
This effectively means destroying all non-active views and all related view components / objects.
However you can override this default behaviour by setting the destructionPolicy on every view to destructionPolicy="never".
This blog post will explain the basic understanding you will need to obtain.
Cheers
Related
I just started developing a test automation for an iOS app using Appium. I have to click several buttons in the app one after another with different XPath/Accessability ids.
I wondered, when to use the wait.until(ExpectedConditions.visibilityOf Element) expression.
Example:
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//XCUIElementTypeApplication[#name=\"app\"]/XCUIElementTypeWindow[1]/XCUIElementTypeOther/XCUIElementTypeTabBar/XCUIElementTypeButton[3]")));
Should I check every time before I click a button if this button is actually visible or existing on the current state of the app or is this just unnecessary and time-wasting?
In my opinion, you should use ExpectedConditions in two case:
Screen load takes long, so you not ending up trying to click something that has not loaded yet. If you find your tests flaky (sometimes pass some times fails) then this probably the main reason why it happens
If you have something like ajax on your screen you want to make sure the data is changed on the page. (Example is you created a post on Facebook, and want to make sure content displayed)
I am trying to figure out ways to authenticate a user and load the application (while showing a preloader) in Adobe Air [desktop application, and not web based flex app].
This is what I have been able to achieve so far:- A window asks for login details, once validated I make the login window invisible and open an instance of the application's main window. There are 2 problems with this:-
I have to open a new window (2 windows in total). It would rather look better if I was able to simply show the login form in one state and the main application view in another state. I tried that too, but the problem is that besides the view component, flash does execute all the actionscript and keeps the other state ready. There is some application view centric actionscript which starts throwing null reference errors etc. On top of that, the whole things takes a while to show up as both views are created, though only 1 of them is shown
I'd like to show a preloader once the user is authenticated, until the main application view is loaded
In a nutshell, this is what I am trying to do:-
Load the login window as fast as possible and stop there (actionscript in other parts of the application should not run)
Post authentication, load the main view of the application. Show a preloader until the loading is done
Load the main view in the same window (rather than opening a new window and making the login one invisible)
Need help and direction as to how this could be executed.
Thanks!
UPDATE 1
Ok, so now I've managed to consolidate the functionality in a single window. however, the transition between states is not a smooth one.
State 1 is the login screen. If the user enters the correct login credentials, State 2 of the view becomes active.
Now for State 2 to load (its a bunch of UI components and a grid with loads of data) it takes time. Until then, the application blanks out and then all of it is shown in a jerk. Can the transition be made much smoother? Just showing 'Loading...' would suffice. Because State 2 won't show up until all of it has been constructed and State 1 dies away as soon as I change the current state to State 2. Is there any way to monitor the progress and changing the state only when the next state has been loaded!
UPDATE 2
Ok, I got the transition animation to work between states. However, there still exists a problem with the transition switch. The problem is that the state I switch to after login has been verified has a lot of components and shows a lot of data.
Is there a way I can attach Listeners (if any), which I can fire when the state loading is complete and view has been generated! The current jerk like effect in the transition is because the state has changed but the view has not completed yet.
State Change to State 2 is not smooth as State 2 loads about 10000 rows of data from database. Is there a way I can change the state visibly for the user, after state 2 has been completely drawn out and has pulled in all data? creationComplete doesn't help much here.
In short, is there a way to start loading a state from an initial state and make it visible only when its complete loaded? i.e. can I fire an event from state 1 to load state 2, but to visibly transition to state 2 only when state 2 is completely loaded..
UPDATE 3
After a week of firefighting, posting a bounty and scavenging through the web I have still not been able to fix this! My application window becomes unresponsive for the time the UI is created and data is loaded. In Windows, it even shows 'Not Responding' at the window title bar for about 5 seconds. So its the UI getting stuck because the data is taking some time to be fetched and loaded - all of this happens in a single thread by default.
How do people who develop based on Adobe Air do this? I've mostly always seen a loading screen before the actual game is loaded - and when its loaded, its fully functional. There has to be a way!
The time consuming problem of loading 10000 rows in a grid can come in any web based language in any web application because web application needs to run in the environment of a web browser which has its own resource limitation.
So what I would suggest is that you don't load all 10000 records at loading the view. Instead load 1000 records first and then keep a link or button with label "Next" or "Show More" like and on that click bring the next bunch of 1000 records from the database. This way you can accomplish your task.
Thanks,
Jigar Oza
problem is I have a spark Tabbar, with many forms in each tab.
But I have a single global save button. Problem is, if I don't open a Tab,
it doesn't get initialized and therefore the forms it contains do not exist..
How Can I make it as if the user had clicked on every tab?
The best way to handle this is to have a data model that each tab is displaying and editing, rather than trying to go in and read the values out of the controls in each tab, and save those. This is at the heart of MVC.
However, if you're too invested in your current architecture to be able to change it and you are using a ViewStack with your TabBar, you may find that setting creationPolicy to "all" does what you want. If you're using States, I don't think you can force all of them to be instantiated without putting your application into each State at least once.
When I try to access the hidden TABs of my tab navigator control in action script, it returns a null error. But it works OK if I just activate the control in the user interface once. Obviously the control is not created until I use it. How do I make all the tabs automatically created by default ?
<mx:TabNavigator creationPolicy="all"/>
That should do it. Deferred instanciation is a feature, but sometimes it is a hassle.
The Flex framework is optimizing creation be default (creationPolicy="auto") so if you have a configuration dialog with a lot of tabs, for example, and the most useful tab is the first one, your application does not spend time and memory initializing the tabs that the user never sees.
This makes a lot of difference when dialogs like this never release, and is a good default to go with.
One thing to look at is using a private variable in your dialog/form instead of pushing the data to the control on the hidden page. This style treats the whole form as if it were a component, which it sort of is. To repeat: the MXML form/dialog/canvas is a class, and it can have data and methods in addition to containing other components.
Cheers
On a side note, I've run into the deferred-loading policy in a multi-state application, and circumvented it by forcing all elements to be included and invisible in the initial state. Something to consider, but only as a hack.
I came across this topic today while investigating something very strange. Doing certain things in our Flex app can cause the number of frames rendered to rocket, from 12fps to ~30fps: loaded animations start playing at high speed and the GUI starts to lock up.
Since everything I've read on Flex/Flash hammers home the point "the frame rate is capped at the fps set in the top level app", it seems the only way these extra renders can be happening is due to some events causing them (no programmatic changes to the stage's framerate are done anywhere). Since it only happens when I put my update logic in the ENTER_FRAME handler, I'm trying to figure out what might be happening which to apparently causing Flex to go render-crazy.
Hypothesis: something in my update function is triggering an immediate screen update, this raises another ENTER_FRAME immediately, which means my update loop gets called, which triggers another immediate screen update, ...
We have Flex components used in our GUI, if this is a factor. I don't really know where to go next on this.
Clarifications:
When I say things speed up, there
are two ways this manifests.
Firstly, my ENTER_FRAME handler gets
called far more often.
Secondly, a
loaded Flash SWF with a looping
animation built in suddenly speeds
up to te point it looks silly.
I am not using updateAfterEvent, I only
found this existed when researching
this problem. Apparently, some
events on Sprite subclasses
automatically call this and I wonder
if that's the root cause.
I am not doing any direct messsing about with rendering at all. Background animations play automatically as they have timelines built-in from CS3 authoring, all our update function does is change the position of DisPlayObjects or add/remove them etc
Update:
I added a label to my app to print out stage.frameRate, and discovered at certain times, it suddenly changes from 12 to 1000 (the maximum allowed value). While it was trivial to add a line to my ENTER_FRAME handler to reset it that's hardly a big help.
Also, even doing this, the rendering is all messed up. Certain actions (like raising an Alert popup) make it all spring back into life.
Unfortunately, I am not able to view the source of the Stage class to set a breakpoint on the setter property.
That's very interesting about the Flex loading 'set to 1000fps' thing. What we have are several Flex applications which all provide a common interface. A master app is in charge of loading these modules as required through the SWFLoader class. However, the loading process already takes into account the delayed loading... when the SWF loads we then wait for the APPLICATION_COMPLETE from the SystemManager. Once this is received, shouldn't the applications completion have occurred?
Flex sets the frame rate to 1000 during "phased instantiation" of Flex components, which occurs only during initial load of a flex swf. This allows it to build all components very quickly.
Are you waiting for the Flex app to be fully loaded and constructed? You should be waiting for FlexEvent.CREATION_COMPLETE before working with your Flex content.
If you would like a reference to where this occcurs, look in the Flex LayoutManager class, line 326 (using Flex SDK 3.0.194161), in the setter for the property usePhasedInstantiation.
Update:
APPLICATION_COMPLETE should have you covered for the initial load.
This actually happens any time components are created directly from MXML. So there are a few other cases to look for. Are you using any Repeaters? Do you use any navigation containers that are building their children on demand?
One thing I'm not clear on - are you seeing that the actual screen refreshes are occurring faster than the published framerate? Or is it that your animations are moving faster but the screen refreshes are unchanged? (i.e., it used to move 10 pixels per second, but now it moves faster than that, regardless of how often the screen is drawn.)
An easy way to check this would be to try publishing your content at 1 fps. It should be clear whether the screen is redrawing once per second, but animated elements are being moved more frequently than that, or whether the screen is actually updating more frequently.
If the latter, are you using any updateAfterEvent() methods in your code? This can cause actual screen refreshes to occur faster than the published framerate. It shouldn't affect ENTER_FRAME events though. You should still only get one of those per frame update.
Alternately, are the things you're animating just Sprites and so on, or are you implementing them as Flex components, and trying to redraw them with invalidate() methods and RENDER events and so on?
If you could clarify a few of these points in the question the answer might be clearer. Thanks...
Thanks for the clarifications. If a loaded clip with a animation (I assume you mean a frame animation) is speeding up, then that certainly sounds like something is changing your playback framerate, as opposed to other things that could be going on. With that said it's not a problem I've seen crop up before, but I do think there are some things you could try that ought to narrow down where the problem is:
You might as well try tracing out stage.frameRate during the speed-up. Presumably nothing ought to be changing your framerate, but since that would explain your issues you might as well rule it out.
Try removing as many GUI components as possible and seeing if the problem still occurs, if it's possible to trigger the problem without them.
One sanity check you could try, if it's feasible, is to copy some of the contents of your game into a fresh project and try it there. Sometimes mysterious issues like this happen because some class or SWC is being imported somewhere that everyone forgot about.
You could try driving your code from a different event. For example, as far as I know driving it from Event.EXIT_FRAME or Event.FRAME_CONSTRUCTED ought to look the same, but if it doesn't then that's a hint. Alternately, you could try driving it from something like a keyboard event or MouseEvent.MOUSE_MOVE. Then if updates occur even though you're not firing events, you'll know something else is driving things besides your event loop.
Those are the things I'd try, anyway. Hope you track it down...