[TIMOB-15105] Android: Opening heavyweight window delayed by following heavy operations
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | High |
Status | Closed |
Resolution | Won't Fix |
Resolution Date | 2014-04-14T21:24:17.000+0000 |
Affected Version/s | Release 3.1.2 |
Fix Version/s | Release 3.3.0 |
Components | Android |
Labels | android, heavyweight, open, triage, window |
Reporter | Fokke Zandbergen |
Assignee | Allen Yeung |
Created | 2013-09-03T08:52:03.000+0000 |
Updated | 2014-05-08T06:35:24.000+0000 |
Description
If opening a heavyweight window is followed by heavy operations, the window won't show until those computations are done.
Steps to reproduce
Execute the following code:
var red = Ti.UI.createWindow({backgroundColor:'red',modal:false});
red.addEventListener('open', function () {
Ti.API.debug('opened red');
});
Ti.API.debug('open red');
red.open();
var green = Ti.UI.createWindow({backgroundColor:'green',modal:false,layout:'vertical'});
green.addEventListener('open', function () {
Ti.API.debug('opened green');
});
for (var i = 0; i < 5000; i++) {
green.add(Ti.UI.createView({backgroundColor:'blue',top:5,height:5}));
}
Ti.API.debug('open green');
green.open();
The console will say red opened a few seconds before green:
10:34:43 [DEBUG] open red
10:34:46 [DEBUG] open green
10:34:46 [DEBUG] opened red
10:34:51 [DEBUG] opened green
But on the device you won't see the red window at all.
Quick analysis
Looking at the Titanium Android [WindowProxy](https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/ui/src/java/ti/modules/titanium/ui/WindowProxy.java#L294), line 294 I see that the open event is fired when the activity is created. So I guess this means it's not an Titanium bug but an Android one that actual showing the window is delayed by the heavy computation that follows.Notes
- When you change the red window to be lightweight it works fine. - When you wrap everything after line 6 insetTimeout
statement it works fine.
- When you replace adding the blue views by a non-UI/non-Proxy heavy computation, the problem stays the same.
Hello, on the side, this is the expected behavior since all those operations are running only in the UI thread. Still, moving to mobile, so the platform team can give us their opinion. Best, Mauro
It might explain it, but it's not what you'd want. And why then it doesn't happen on a lightweight window? And why does it fire
open
even if it clearly isn't? Not being able to depend onopen
being fired after actually having opened the window causes major problems if you want to act on the window following the event.I've run into situations where the JS and native side get out of sync because of this behavior. Basically, JS processing continues, blocking/delaying the native side. You end up trying to access objects & properties that don't yet exist (on the native side) which causes your app to crash with a cryptic segfault error. Error reporting is minimal and confusing, and solutions to the situation are not obvious.
For HW windows, the "open" event is fired after the activity has been created and all the children views have been added, but before all the views are measured, laid out and rendered. That's why there is a delay between firing the "open" event and displaying all the views on the screen when 5000 views need to be measured, laid out and drawn. The red window does not show before the green window opens is because after the activity for red window has been created, it immediately creates another new activity for green window. Therefore, Android puts the first activity (red window) on pause and decides not to draw this activity. This behavior can be confirmed in a native Android app.
[~pwang] thanks a lot for this clarification! Now, do you think we should consider postponing firing the
open
event until everything is layed out? Or maybe have anotherlayout
event that fires when this happend (and not every time the layout changes likepostlayout
does?)It won't be a simple task to introduce a new event like that. We don't plan on resolving this for 3.2.0, but we'll definitely look into what is involved in introducing a new event that fires after all the views have been rendered.
Since this is won't fix. Hence closing the issue.