[TIMOB-1774] Android: Reopening a window sometimes fails with runtime error
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | Medium |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2011-04-17T01:57:08.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 1.5.0 |
Components | Android |
Labels | android, defect |
Reporter | Bill Dawson |
Assignee | Bill Dawson |
Created | 2011-04-15T03:01:55.000+0000 |
Updated | 2011-04-17T01:57:08.000+0000 |
Description
This is a bit of a complex one and hard to test from a QE perspective.
Because our memory cleanup (and the releasing / garbage
collecting of objects) has improved, we actually have a weird
situation where if you re-open an existing window (meaning, call
.open
on an existing window proxy) that had previously
been closed, the activity attached to its context might be null
(garbage collected). The .open()
process creates our
window view instance, which in turn creates an Android intent to
open a new activity. The code to create the intent is in the
TiUIWindow constructor:
if (newActivity){
lightWeight = false;
Activity activity = proxy.getTiContext().getActivity();
Intent intent = createIntent(activity, options);
The problem is that the getActivity()
you see there
might be null, because the proxy's context -- from the previous
time the window was closed -- has been released and its activity
cleaned up.
During the creation of a window, the proxy's context is actually switched from the context it was created in to the context that it creates -- and that's the context that gets cleaned up when it's closed.
The fix for this is: when the window is closed, switch its context back to its creating context (from which it was switched away when it created its own context the last time it was opened.)
Comments
- Bill Dawson 2011-04-15
By the way, you can get away with this error not happening -- it's just that if a garbage collection occurs and wipes out that old activity, then it will happen when the window is reopened. Using DDMS I can force a garbage collection and get the problem to occur everytime.
- Bill Dawson 2011-04-15
Relevant commit, for which , as so often, i screwed up the comment so it didn't get here automatically:
http://github.com/appcelerator/titanium_mobile/commit/6c2b0d450f4a879a2d48a2376564870d4ad06e8b"> http://github.com/appcelerator/titanium_mobile/commit/6c2b0d450f4a8...
- Bill Dawson 2011-04-15
Thomas,
This might be tough one to test. You need a tool like DDMS to force a garbage collection. In case you want to try, here's a fail case consisting of three files:
app.js:
var win = Titanium.UI.createWindow({ title:'Test Anything', backgroundColor:'#fff', url: 'w1.js', fullscreen:true, exitOnClose: true }); win.open();
w1.js:
var win = Ti.UI.currentWindow; var win2; var btn = Ti.UI.createButton({ title: 'open subwindow' }); btn.addEventListener('click', function(){win2.open();}); win.add(btn); win2 = Ti.UI.createWindow({ url: 'w2.js', backgroundColor:'green', fullscreen: true });
w2.js:
var win = Ti.UI.currentWindow; var lbl = Ti.UI.createLabel({color: 'black',text: 'Hit back button to go back'}); win.add(lbl);
Then follow these steps:
- Open the app
- Click the button to open the second window.
- Click the Android back button (hardware) to go back to the first window.
- Force a garbage collection. (DDMS)
- Click the button to open the second window. -- You should get a Force Close.
To test the fail case, you need a version prior to the above commit (obviously :) ) but still very recent, like in the last two days.
- Thomas Huelbert 2011-04-15
closing, 1.6 g1 device, 2.2 simulator. Thanks for the debug flag info for device, as well as the test case.