Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-1774] Android: Reopening a window sometimes fails with runtime error

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2011-04-17T01:57:08.000+0000
Affected Version/sn/a
Fix Version/sRelease 1.5.0
ComponentsAndroid
Labelsandroid, defect
ReporterBill Dawson
AssigneeBill Dawson
Created2011-04-15T03:01:55.000+0000
Updated2011-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

  1. 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.

  2. 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...

  3. 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.

  4. 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.

JSON Source