{ "id": "135076", "key": "TIMOB-17536", "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": [], "resolution": { "id": "5", "description": "All attempts at reproducing this issue failed, or not enough information was available to reproduce the issue. Reading the code produces no clues as to why this behavior would occur. If more information appears later, please reopen the issue.", "name": "Cannot Reproduce" }, "resolutiondate": "2017-07-24T22:11:27.000+0000", "created": "2014-08-20T22:46:00.000+0000", "priority": { "name": "Low", "id": "4" }, "labels": [ "TCSupport" ], "versions": [ { "id": "15422", "description": "Release 3.3.0", "name": "Release 3.3.0", "archived": false, "released": true, "releaseDate": "2014-07-16" } ], "issuelinks": [], "assignee": { "name": "emerriman", "key": "emerriman", "displayName": "Eric Merriman ", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2017-07-24T22:11:27.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": "h4. Problem Description\r\nThe customer is using setInterval for animating a loader, when the window that contains the loader is closed, the customer does a clearInterval and the app crashes. \r\n\r\nh4. Steps to reproduce\r\n1. Create a new mobile project (classic ttitanium)\r\n2. Paste the code of the testcase: \r\n{code}\r\nvar win = Titanium.UI.createWindow({\r\n title : 'Test',\r\n backgroundColor : '#fff'\r\n});\r\n \r\nvar v_progress_bar = Ti.UI.createView ({\r\n left: 10,\r\n right: 10,\r\n height: 10,\r\n backgroundColor: '#333'\r\n});\r\n \r\nvar v_progress_indicator = Ti.UI.createView ({\r\n left: 0,\r\n width: 0,\r\n top: 0,\r\n bottom: 0,\r\n backgroundColor: '#2F7CC1'\r\n});\r\n \r\nv_progress_bar.add (v_progress_indicator);\r\nwin.add (v_progress_bar);\r\n \r\nvar current_fill_width = 0;\r\nvar duration = 60000;\r\nvar start_time = new Date().getTime ();\r\n \r\nfunction update_position ()\r\n{\r\n var now = new Date().getTime ();\r\n var elapsed = now - start_time;\r\n if (elapsed > duration) {\r\n elapsed = duration;\r\n }\r\n \r\n // this should cause a crash after the window is closed...\r\n var fill_width = parseInt (elapsed / duration * v_progress_bar.size.width);\r\n if (fill_width != current_fill_width)\r\n {\r\n Ti.API.info (\"setting progress_bar_width...\");\r\n v_progress_indicator.setWidth (fill_width);\r\n current_fill_width = fill_width;\r\n }\r\n}\r\n \r\nvar up_int = setInterval (update_position, 250);\r\n \r\nwin.addEventListener ('close', function (e) {\r\n Ti.API.info ('win closed.');\r\n clearInterval (up_int); \r\n});\r\n \r\nwin.open();\r\n{code}\r\n3. Run it in a device\r\n4. Once the bar starts loading, click on the back button of the device.\r\n5. The app will crash. \r\n\r\nh4. Workarund\r\nThe same customer, if rearranges the code like this:\r\n\r\n{code}\r\nvar win = Titanium.UI.createWindow({\r\n title : 'Test',\r\n backgroundColor : '#fff'\r\n});\r\n \r\nvar v_progress_bar = Ti.UI.createView ({\r\n left: 10,\r\n right: 10,\r\n height: 10,\r\n backgroundColor: '#333'\r\n});\r\n \r\nvar v_progress_indicator = Ti.UI.createView ({\r\n left: 0,\r\n width: 0,\r\n top: 0,\r\n bottom: 0,\r\n backgroundColor: '#2F7CC1'\r\n});\r\n \r\nv_progress_bar.add (v_progress_indicator);\r\nwin.add (v_progress_bar);\r\n \r\nvar current_fill_width = 0;\r\nvar duration = 60000;\r\nvar start_time = new Date().getTime ();\r\n \r\nvar progress_bar_width = 0;\r\n \r\nfunction update_position ()\r\n{\r\n var now = new Date().getTime ();\r\n var elapsed = now - start_time;\r\n if (elapsed > duration) {\r\n elapsed = duration;\r\n }\r\n \r\n // don't try to access size from within setInterval(); when the window is closed\r\n // on android, you'll get a nasty NullPointerException, even if you try to remove\r\n // the event listener on window close\r\n var fill_width = parseInt (elapsed / duration * progress_bar_width);\r\n if (fill_width != current_fill_width)\r\n {\r\n Ti.API.info (\"setting progress_bar_width...\");\r\n v_progress_indicator.setWidth (fill_width);\r\n current_fill_width = fill_width;\r\n }\r\n}\r\n \r\n// get the size once at startup, and get it any time the orientation changes...\r\n// if we didn't remove the event listener, it would get triggered every time\r\n// we resized the progress indicator, which would mean we'd get triggered\r\n// during the window close; accessing the size property of a view during\r\n// the window close will cause a NullPointer Exception.\r\nfunction on_new_size (e)\r\n{\r\n Ti.API.info (\"checking progress_bar_width...\");\r\n progress_bar_width = v_progress_bar.size.width;\r\n Ti.API.info (\"progress bar width: \" + progress_bar_width);\r\n win.removeEventListener ('postlayout', on_new_size); \r\n}\r\n \r\nwin.addEventListener ('postlayout', on_new_size);\r\n \r\nTi.Gesture.addEventListener('orientationchange',function(e) {\r\n win.addEventListener ('postlayout', on_new_size);\r\n});\r\n \r\nvar up_int = setInterval (update_position, 250);\r\n \r\nwin.addEventListener ('close', function (e) {\r\n Ti.API.info ('win closed.');\r\n clearInterval (up_int); \r\n});\r\n \r\nwin.open();\r\n{code}\r\n\r\nwill work just fine. \r\n\r\nh4. Community Discussion\r\nhttp://developer.appcelerator.com/question/177097/manipulating-a-view-from-setinterval-callback-crashes-app", "attachment": [], "flagged": false, "summary": "Android: createInterval/setInterval crashes app", "creator": { "name": "mpmiranda", "key": "mpmiranda", "displayName": "Mauro Parra-Miranda", "active": true, "timeZone": "America/Mexico_City" }, "subtasks": [], "reporter": { "name": "mpmiranda", "key": "mpmiranda", "displayName": "Mauro Parra-Miranda", "active": true, "timeZone": "America/Mexico_City" }, "environment": null, "comment": { "comments": [ { "id": "319576", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Setting as medium due to existence of workaround.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-08-20T22:56:08.000+0000", "updated": "2014-08-20T22:56:08.000+0000" }, { "id": "324686", "author": { "name": "jithinv@exalture.com", "key": "jithinv@exalture.com", "displayName": "jithinpv", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Issue reproduces\r\n\r\nTitanium SDK version 3.4.0 master, 3.3.0.GA\r\nTitanium Studio, build: 3.3.0.201407100905\r\nTitanium Command-Line Interface\r\nCLI version 3.3.0, \r\nAndroid device : Motorola Moto G, Android version : 4.4.4", "updateAuthor": { "name": "jithinv@exalture.com", "key": "jithinv@exalture.com", "displayName": "jithinpv", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-09-19T10:15:53.000+0000", "updated": "2014-09-19T10:15:53.000+0000" }, { "id": "424622", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "I am unable to reproduce this issue with the following environment;\r\nPixel (7.1)\r\nStudio 4.9.0.201705302345\r\nTi SDK 6.1.1 GA\r\nAppc NPM 4.2.9\r\nAppc CLI 6.2.2\r\nTi CLI 5.0.14\r\nAlloy 1.9.11\r\nXcode 8.2 (8C38)\r\nNode v4.8.2\r\nJava 1.8.0_131", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-07-24T22:11:27.000+0000", "updated": "2017-07-24T22:11:27.000+0000" } ], "maxResults": 3, "total": 3, "startAt": 0 } } }