{ "id": "63840", "key": "TIMOB-3208", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "11244", "name": "Release 1.7.0", "archived": true, "released": true, "releaseDate": "2011-06-13" }, { "id": "11245", "name": "Sprint 2011-10", "archived": true, "released": true, "releaseDate": "2011-03-14" }, { "id": "11364", "description": "Mobile 1.8.0 M11", "name": "Sprint 2011-32", "archived": true, "released": true, "releaseDate": "2011-08-15" }, { "id": "11331", "description": "", "name": "Release 1.8.0", "archived": true, "released": true, "releaseDate": "2011-10-31" }, { "id": "12092", "description": "", "name": "Sprint 2011-52", "archived": true, "released": true, "releaseDate": "2011-12-30" }, { "id": "12593", "name": "Release 2.0.0", "archived": false, "released": true, "releaseDate": "2012-03-30" }, { "id": "12677", "description": "Release 1.8 Service Pack 1", "name": "Release 1.8.1", "archived": true, "released": true, "releaseDate": "2012-01-31" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2011-12-28T11:19:53.000+0000", "created": "2011-04-15T03:39:29.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "module_window", "qe-testadded", "regression", "release-1.7.0", "reported-1.6.0" ], "versions": [ { "id": "11570", "description": "", "name": "Release 1.7.2", "archived": true, "released": true, "releaseDate": "2011-07-21" } ], "issuelinks": [ { "id": "14384", "type": { "id": "10002", "name": "Duplicate", "inward": "is duplicated by", "outward": "duplicates" }, "outwardIssue": { "id": "83771", "key": "TIMOB-6648", "fields": { "summary": "Android: onCreateOptionsMenu Regressions in 1.9.0 from 1.7.5", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } }, { "id": "10224", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "64765", "key": "TIMOB-3696", "fields": { "summary": "Confirm TIMOB-3208", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "5", "description": "The sub-task of the issue", "name": "Sub-task", "subtask": true } } } } ], "assignee": { "name": "ayeung", "key": "ayeung", "displayName": "Allen Yeung", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2012-02-03T15:50:33.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "{html}

Problem

\r\n

If you open a heavyweight window when the user touches a menu\r\nitem, you can easily cause a null pointer exception to be thrown\r\nand the app to crash.

\r\n

Theory

\r\n

Based on the error message, we're hitting the NPE in our call to\r\ncreate a new intent on line 528 of TiUIWindow.java. Because\r\nTiActivity.class is not null, activity must be null. This is set on\r\nline 185 of the same file, and passed to the createIntent method.\r\nMy theory is that there is an interim period between when the menu\r\ncloses and the window regains focus during which\r\nproxy.getTiContext().getActivity() will return null, and cause the\r\nNPE.

\r\n

Sample Code

\r\n

Drop the following in an app.js:

\r\n
\r\n// open a heavyweight window\r\nvar win = Titanium.UI.createWindow({ backgroundColor: '#fff', fullscreen: true });\r\nwin.add(Ti.UI.createLabel({ text: 'Press your hardware menu button!' }));\r\nwin.open();\r\nvar modal = Ti.UI.createWindow();\r\n\r\n// keep a pointer to the current activity\r\nvar currentActivity = win.activity;\r\n\r\n// and make an options menu\r\ncurrentActivity.onCreateOptionsMenu = function(e) {\r\n\r\n    // this menu item will effectively work off \"proxy.getTiContext().getActivity()\",\r\n    // which can be null if the timing is just right when the menu closes and the modal opens\r\n    e.menu.add({ title: 'Crashes Often' }).addEventListener('click', function() {\r\n        // simulate some heavy activity to get the modal ready; having this busy\r\n        // wait present is what makes this bug reproducible\r\n        for (var i = new Date().getTime() + 1000; i > new Date().getTime();) {\r\n        }\r\n        modal.open({ modal: true });\r\n        setTimeout(function() {\r\n            modal.close();\r\n        }, 50);\r\n    });\r\n\r\n    // but we explicitly set the activity in this one to our outer activity (the main activity)\r\n    // so it will never be null\r\n    var intent = Ti.Android.createIntent({\r\n        url: 'loginModalWindow.js'\r\n    });\r\n    intent.putExtra('modal', true);\r\n    e.menu.add({ title: 'Never Crashes' }).addEventListener(\"click\", function() {\r\n        // simulate some heavy activity; it won't make a difference\r\n        for (var i = new Date().getTime() + 1000; i > new Date().getTime();) {\r\n        }\r\n        // start the activity; it will fire off without a problem\r\n        currentActivity.startActivity(intent);\r\n    });\r\n\r\n};\r\n
\r\n

now drop the following into your tiapp.xml:

\r\n
\r\n    <android xmlns:android=\"http://schemas.android.com/apk/res/android\">\r\n        <activities>\r\n            <activity url=\"loginModalWindow.js\" android:theme=\"@android:style/Theme.Dialog\" />\r\n        </activities>\r\n    </android>\r\n
\r\n

and finally drop the following in loginModalWindow.js:

\r\n
\r\nvar win = Ti.UI.currentWindow;\r\nwin.modal = true;\r\n\r\nsetTimeout(function() {\r\n    win.close();\r\n}, 50)\r\n
\r\n

This sample app has two menu items, named \"Crashes Often\" and\r\n\"Never Crashes\". They both launch modal windows that close\r\nthemselves right away. The difference is the method they use.\r\n\"Crashes Often\" uses the Titanium way of opening a modal window.\r\n\"Never Crashes\" uses a more native Android way to open the modal,\r\nand is not reliant on Titanium automagically determining the\r\ncurrent activity that should launch our modal activity. Note that\r\nyou may need to try \"Crashes Often\" a couple of times before the\r\napp will freeze, crash, and you'll see the NPE in your logs.

\r\n

Exception

\r\n
\r\nE/TiUncaughtHandler(11317): (main) [1236,5053] Sending event: exception on thread: main msg:java.lang.NullPointerException; Titanium 1.7.0,2011/02/18 18:13,16c2c7\r\nE/TiUncaughtHandler(11317): java.lang.NullPointerException\r\nE/TiUncaughtHandler(11317):     at android.content.ComponentName.<init>(ComponentName.java:75)\r\nE/TiUncaughtHandler(11317):     at android.content.Intent.<init>(Intent.java:2652)\r\nE/TiUncaughtHandler(11317):     at ti.modules.titanium.ui.TiUIWindow.createIntent(TiUIWindow.java:528)\r\nE/TiUncaughtHandler(11317):     at ti.modules.titanium.ui.TiUIWindow.createNewActivity(TiUIWindow.java:186)\r\nE/TiUncaughtHandler(11317):     at ti.modules.titanium.ui.TiUIWindow.<init>(TiUIWindow.java:110)\r\nE/TiUncaughtHandler(11317):     at ti.modules.titanium.ui.WindowProxy.handleOpen(WindowProxy.java:98)\r\nE/TiUncaughtHandler(11317):     at org.appcelerator.titanium.proxy.TiWindowProxy.handleMessage(TiWindowProxy.java:67)\r\nE/TiUncaughtHandler(11317):     at ti.modules.titanium.ui.WindowProxy.handleMessage(WindowProxy.java:85)\r\nE/TiUncaughtHandler(11317):     at android.os.Handler.dispatchMessage(Handler.java:95)\r\nE/TiUncaughtHandler(11317):     at android.os.Looper.loop(Looper.java:123)\r\nE/TiUncaughtHandler(11317):     at android.app.ActivityThread.main(ActivityThread.java:4370)\r\nE/TiUncaughtHandler(11317):     at java.lang.reflect.Method.invokeNative(Native Method)\r\nE/TiUncaughtHandler(11317):     at java.lang.reflect.Method.invoke(Method.java:521)\r\nE/TiUncaughtHandler(11317):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)\r\nE/TiUncaughtHandler(11317):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)\r\nE/TiUncaughtHandler(11317):     at dalvik.system.NativeStart.main(Native Method)\r\nE/AndroidRuntime(11317): Uncaught handler: thread main exiting due to uncaught exception\r\n
\r\n

Tested On

\r\n

Titanium SDK version: 1.7.0 (02/18/11 18:13 316c2c7)
\r\nBROKEN on Android EPIC 4G 2.1

\r\n

Associated Helpdesk Ticket

\r\n

http://developer.appcelerator.com/helpdesk/view/75121

{html}", "attachment": [ { "id": "22523", "filename": "app.zip", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-08-10T12:22:33.000+0000", "size": 1205, "mimeType": "application/zip" }, { "id": "18277", "filename": "resources.zip", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-04-15T03:39:29.000+0000", "size": 825520, "mimeType": "application/zip" } ], "flagged": false, "summary": "Android: Heavyweight Windows Opened by Menu Items Often Cause Null Pointer Exceptions", "creator": { "name": "dtoth", "key": "dtoth", "displayName": "Dawson Toth", "active": true, "timeZone": "America/New_York" }, "subtasks": [], "reporter": { "name": "dtoth", "key": "dtoth", "displayName": "Dawson Toth", "active": true, "timeZone": "America/New_York" }, "environment": null, "comment": { "comments": [ { "id": "130290", "author": { "name": "dtoth", "key": "dtoth", "displayName": "Dawson Toth", "active": true, "timeZone": "America/New_York" }, "body": "{html}

Workaround

\n

Incidentally... there is a workaround that I did not explicitly\nmention. If you take a more manual approach to launching modal\nwindows, the NPE can be avoided entirely. Take a look at the \"Never\nCrashes\" menu item and at what it is doing.

{html}", "updateAuthor": { "name": "dtoth", "key": "dtoth", "displayName": "Dawson Toth", "active": true, "timeZone": "America/New_York" }, "created": "2011-04-15T03:39:29.000+0000", "updated": "2011-04-15T03:39:29.000+0000" }, { "id": "130291", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "{html}

Spawned #3337 in order to address issue with HW windows\nnot setting the opened state correctly when closing. This applies\nto non modal windows.

{html}", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-04-15T03:39:31.000+0000", "updated": "2011-04-15T03:39:31.000+0000" }, { "id": "130292", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "{html}

Upon further investigation, #3337 has\nbeen set to invalid and fix will be attached to this ticket.

{html}", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-04-15T03:39:31.000+0000", "updated": "2011-04-15T03:39:31.000+0000" }, { "id": "130293", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "{html}

(from [56ff1de427f78c3e5e69b719a005e1deb102d611])\n[#3208 state:fixed-in-qa] Make sure opened flag\nis set correctly when closing HW window

\n

opened window was not being set correctly upon HW window close.\nThis was resulting in the incorrect conext being associated with\nthe window proxy and would sometimes resul in an exception when\nopening the window a second time.
\n\nhttps://github.com/appcelerator/titanium_mobile/commit/56ff1de427f7...

{html}", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-04-15T03:39:31.000+0000", "updated": "2011-04-15T03:39:31.000+0000" }, { "id": "130294", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "{html}

Please use attached resources directory (modified version of\noriginal test) to verify fix. While this fix resolves the reported\nexception, it should be noted that there is a delay when closing a\nmodal window that is opened from the options menu. The onDestroy\nlogic does not actually fire for the window until the menu is\nopened again or there are activity changes such as orientation\nchange.

\n

During testing this behavior was seen to not have any negative\nside effects but still documenting here in case this info needs to\nbe referenced in the future.

{html}", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-04-15T03:39:32.000+0000", "updated": "2011-04-15T03:39:32.000+0000" }, { "id": "130295", "author": { "name": "nhuynh", "key": "nhuynh", "displayName": "Natalie Huynh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "{html}

Tested with Titanium SDK version: 1.7.0 (03/23/11 09:50\n87caf1e...) on
\nEmulator 2.1
\nNexus S 2.3.2

\n

No longer catching exception

{html}", "updateAuthor": { "name": "nhuynh", "key": "nhuynh", "displayName": "Natalie Huynh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-04-15T03:39:32.000+0000", "updated": "2011-04-15T03:39:32.000+0000" }, { "id": "160532", "author": { "name": "avaghti", "key": "avaghti", "displayName": "Alan Vaghti", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Works as expected as on 1.7.1 \r\nversion=1.7.1\r\ntimestamp=06/21/11 14:28\r\ngithash=1293a6d\r\n\r\nHowever pressing 'Never Crashes' causes a force close on 1.7.2 and the latest 1.8.0 build: \"The application BugTest (process com.appcelerator.bugtest) has stopped unexpectedly. Please try again.\" \r\n\r\nversion=1.7.2\r\ntimestamp=07/21/11 09:36\r\ngithash=97c3689\r\n\r\nversion=1.8.0\r\ntimestamp=07/25/11 14:29\r\ngithash=65a5393...\r\n\r\nTested on a Droid running Android 2.2.2", "updateAuthor": { "name": "avaghti", "key": "avaghti", "displayName": "Alan Vaghti", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-07-25T15:26:35.000+0000", "updated": "2011-07-26T11:22:46.000+0000" }, { "id": "160534", "author": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Please look into this.", "updateAuthor": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-07-25T15:38:47.000+0000", "updated": "2011-07-25T15:38:47.000+0000" }, { "id": "162456", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "Issue reported is a duplicated of #4643. Please refer to #4643 for the work around.\r\n\r\nIn short, the theme specified does not support the features that the custom activity is trying to utilize. In order to address this situation, navBarHidden should be set to true when launching the new activity. I have provided an example of the work around.\r\n", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-08-10T12:21:49.000+0000", "updated": "2011-08-10T12:21:49.000+0000" }, { "id": "162457", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "work around attached for the the problem introduced by setting theme on custom activity", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-08-10T12:22:33.000+0000", "updated": "2011-08-11T16:52:37.000+0000" }, { "id": "176634", "author": { "name": "nhuynh", "key": "nhuynh", "displayName": "Natalie Huynh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Tested with 1.8.0.1.RC3 with rhino/v8, not able to invoke the menu, spoke to Allen, he said he will try to reproduce first before kicking it back. May be an issue with the test case", "updateAuthor": { "name": "nhuynh", "key": "nhuynh", "displayName": "Natalie Huynh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-12-19T17:21:35.000+0000", "updated": "2011-12-19T17:21:35.000+0000" }, { "id": "177345", "author": { "name": "ayeung", "key": "ayeung", "displayName": "Allen Yeung", "active": true, "timeZone": "America/Los_Angeles" }, "updateAuthor": { "name": "ayeung", "key": "ayeung", "displayName": "Allen Yeung", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-12-27T16:44:18.000+0000", "updated": "2011-12-27T16:44:18.000+0000" }, { "id": "179239", "author": { "name": "wluu", "key": "wluu", "displayName": "Wilson Luu", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing bug. Verified fix on:\r\n\r\nSDK build: 1.9.0.v20120112153134\r\nRuntime: V8, Rhino\r\nTitanium Studio, build: 1.0.8.201201122152\r\nDevice: Droid 3 (2.3.4)", "updateAuthor": { "name": "wluu", "key": "wluu", "displayName": "Wilson Luu", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2012-01-13T14:13:57.000+0000", "updated": "2012-01-13T14:13:57.000+0000" } ], "maxResults": 13, "total": 13, "startAt": 0 } } }