{ "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}
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\nBased 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\nDrop 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\nnow 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\nand 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\nThis 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\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\nTitanium SDK version: 1.7.0 (02/18/11 18:13 316c2c7)
\r\nBROKEN on Android EPIC 4G 2.1
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.
Spawned #3337 in order to address issue with HW windows\nnot setting the opened state correctly when closing. This applies\nto non modal windows.
Upon further investigation, #3337 has\nbeen set to invalid and fix will be attached to this ticket.
(from [56ff1de427f78c3e5e69b719a005e1deb102d611])\n[#3208 state:fixed-in-qa] Make sure opened flag\nis set correctly when closing HW window
\nopened 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...
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.
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.
Tested with Titanium SDK version: 1.7.0 (03/23/11 09:50\n87caf1e...) on
\nEmulator 2.1
\nNexus S 2.3.2
No longer catching exception