{ "id": "151794", "key": "TIMOB-20038", "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": "16997", "name": "Release 5.2.0", "archived": false, "released": true, "releaseDate": "2016-02-23" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2016-02-02T08:33:21.000+0000", "created": "2015-10-07T14:33:08.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [ "android" ], "versions": [ { "id": "17049", "name": "titanium 5.0.5", "archived": false, "released": true, "releaseDate": "2015-10-06" } ], "issuelinks": [], "assignee": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2016-04-11T13:19:19.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": "When executing the following code, if there are more than 29 rows, the app will crash when scrolling back up from the bottom of the TableView:\n\n(You may need to try more than 30 rows for the app to crash, as each device may vary this number)\n{code}\nvar section = Ti.UI.createTableViewSection();\nvar numberOfRows = 30;\t//if > 29 the app will crash when scrolling back up from the bottom\n\nfor (var i=0; i < numberOfRows; i++)\t \n{\t\n\t//fill section with rows\t\n\tsection.add(Ti.UI.createTableViewRow({\n\t\theight: 50,\n\t\twidth: Ti.UI.FILL,\n\t\tbackgroundColor: 'green',\n\t\tclassName: 'row' + i\n\t}));\n};\n\nvar table = Ti.UI.createTableView({\n\ttop: 0,\n\tleft: 0,\n\theight: Ti.UI.FILL,\n\twidth: Ti.UI.FILL,\n\tdata: [ section ]\n});\n\nvar window = Ti.UI.createWindow({\n\tfullscreen: true\t\t\n});\n\nwindow.add(table);\nwindow.open();\n{code}\n*The error log from the Studio console is:*\n{code}\n[ERROR] : InputEventReceiver: Exception dispatching input event.\n[DEBUG] : AndroidRuntime: Shutting down VM\n[WARN] : dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x410532a0)\n[ERROR] : TiApplication: (main) [25408,25408] Sending event: exception on thread: main msg:java.lang.ArrayIndexOutOfBoundsException: length=32; index=32; Titanium 3.5.1,2015/03/05 10:08,96875c9\n[ERROR] : TiApplication: java.lang.ArrayIndexOutOfBoundsException: length=32; index=32\n[ERROR] : TiApplication: \tat android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:7127)\n[ERROR] : TiApplication: \tat android.widget.AbsListView.trackMotionScroll(AbsListView.java:5694)\n[ERROR] : TiApplication: \tat android.widget.AbsListView.scrollIfNeeded(AbsListView.java:3424)\n[ERROR] : TiApplication: \tat android.widget.AbsListView.onTouchEvent(AbsListView.java:4099)\n[ERROR] : TiApplication: \tat android.view.View.dispatchTouchEvent(View.java:7350)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2464)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2197)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2470)\n[ERROR] : TiApplication: \tat android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2212)\n[ERROR] : TiApplication: \tat com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2151)\n[ERROR] : TiApplication: \tat com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1480)\n[ERROR] : TiApplication: \tat android.app.Activity.dispatchTouchEvent(Activity.java:2469)\n[ERROR] : TiApplication: \tat android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.dispatchTouchEvent(ActionBarActivityDelegateICS.java:268)\n[ERROR] : TiApplication: \tat com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2099)\n[ERROR] : TiApplication: \tat android.view.View.dispatchPointerEvent(View.java:7535)\n[ERROR] : TiApplication: \tat android.view.ViewRootImpl.deliverPointerEvent(ViewRootImpl.java:3492)\n[ERROR] : TiApplication: \tat android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:3424)\n[ERROR] : TiApplication: \tat android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:4534)\n[ERROR] : TiApplication: \tat android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:4512)\n[ERROR] : TiApplication: \tat android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:4616)\n[ERROR] : TiApplication: \tat android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:171)\n[ERROR] : TiApplication: \tat android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)\n[ERROR] : TiApplication: \tat android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:163)\n[ERROR] : TiApplication: \tat android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:4584)\n[ERROR] : TiApplication: \tat android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:4635)\n[ERROR] : TiApplication: \tat android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)\n[ERROR] : TiApplication: \tat android.view.Choreographer.doCallbacks(Choreographer.java:555)\n[ERROR] : TiApplication:\n[ERROR] : TiApplication: \tat android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)\n[ERROR] : TiApplication: \tat android.os.Handler.handleCallback(Handler.java:615)\n[ERROR] : TiApplication: \tat android.os.Handler.dispatchMessage(Handler.java:92)\n[ERROR] : TiApplication: \tat android.os.Looper.loop(Looper.java:137)\n[ERROR] : TiApplication: \tat android.app.ActivityThread.main(ActivityThread.java:4921)\n[ERROR] : TiApplication: \tat java.lang.reflect.Method.invokeNative(Native Method)\n[ERROR] : TiApplication: \tat java.lang.reflect.Method.invoke(Method.java:511)\n[ERROR] : TiApplication: \tat com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)\n[ERROR] : TiApplication: \tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)\n[ERROR] : TiApplication: \tat dalvik.system.NativeStart.main(Native Method)\n{code}\nI have tried removing the \"className\" property from the TableViewRow, which stops the crashing, but prevents Buttons and other Views inside the TableViewRow redrawing correctly, so must be left in (as indicated by the Appcelerator Platform Docs).\n\nDue to our customers using JellyBean devices, we need the fix in 3.5.1 or 3.5.2, as the devices can't be upgraded to newer Android versions.\n\n*Possible Cause:*\n\nThis may be caused by an issue with 0-Based indexes used in getItemViewType() or getViewTypeCount() in titanium_mobile/android/modules/ui/src/java/ti/modules/titanium/ui/widget/listview/TiListView.java", "attachment": [], "flagged": false, "summary": "Android: TableView crashes when scrolling more than 29 rows", "creator": { "name": "anfen", "key": "anfen", "displayName": "Adam Fennell", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "anfen", "key": "anfen", "displayName": "Adam Fennell", "active": true, "timeZone": "America/Los_Angeles" }, "environment": "Windows 7 (64Bit) \r\nAppcelerator Studio Build: 4.3.2.201510020431 \r\nTi SDK: 3.5.1.GA & 3.5.2.v20150619094811 \r\nCLI: 5.0.2 \r\nDevice: Samsung Galaxy Note 10.1 JellyBean 4.1.2 (API16)", "closedSprints": [ { "id": 536, "state": "closed", "name": "2015 Sprint 25 SDK", "startDate": "2015-12-05T01:30:40.415Z", "endDate": "2015-12-19T01:30:00.000Z", "completeDate": "2015-12-29T03:19:42.127Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "366916", "author": { "name": "anfen", "key": "anfen", "displayName": "Adam Fennell", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Could you let me know if this is something you are looking into? It would be great if I could update our customers, as this is a work stop issue for them.", "updateAuthor": { "name": "anfen", "key": "anfen", "displayName": "Adam Fennell", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-10-15T09:46:10.000+0000", "updated": "2015-10-15T09:46:10.000+0000" }, { "id": "372451", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "The problem here is this:\r\n{code}\r\nclassName: 'row' + i\r\n{code}\r\n\"className\" is used for internal recycling purposes (i.e: speeds up loading time for table view). Currently we support up to 32 different classNames (or row layouts). In your example, there is only one row layout, so you only need one className. Please look at http://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.TableViewRow-property-className for more info.\r\n\r\nI will expose a property to change the default '32', but for this case you should only use one className.", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-12-08T20:07:52.000+0000", "updated": "2015-12-08T20:07:52.000+0000" }, { "id": "372453", "author": { "name": "anfen", "key": "anfen", "displayName": "Adam Fennell", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Thanks for looking into this.\r\n\r\nThe example code I posted was to highlight the issue. In our actual app, we have (or would like to have) 40 rows with different layouts i.e. no rows have the same layout of views.\r\n\r\nAm I right to say then:\r\n1. We would use: *className: 'row' + i* ?\r\n2. We would set the newly exposed property from 32 to 40?\r\n\r\nAlso, would there be a negative effect on performance or memory consumption if this exposed property is, for example, set to 100?", "updateAuthor": { "name": "anfen", "key": "anfen", "displayName": "Adam Fennell", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-12-08T20:22:18.000+0000", "updated": "2015-12-08T20:22:18.000+0000" }, { "id": "372459", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "master PR: https://github.com/appcelerator/titanium_mobile/pull/7558\r\ntesting code:\r\n{code}\r\nvar section = Ti.UI.createTableViewSection();\r\nvar numberOfRows = 35;\t//if > 29 the app will crash when scrolling back up from the bottom\r\n \r\nfor (var i=0; i < numberOfRows; i++)\t \r\n{\t\r\n\t//fill section with rows\t\r\n\tsection.add(Ti.UI.createTableViewRow({\r\n\t\theight: 50,\r\n\t\twidth: Ti.UI.FILL,\r\n\t\tbackgroundColor: 'green',\r\n\t\tclassName: 'row' + i\r\n\t}));\r\n};\r\n \r\nvar table = Ti.UI.createTableView({\r\n\ttop: 0,\r\n\tleft: 0,\r\n\tmaxClassname: 100,\r\n\theight: Ti.UI.FILL,\r\n\twidth: Ti.UI.FILL,\r\n\tdata: [ section ]\r\n});\r\n \r\nvar window = Ti.UI.createWindow({\r\n\tfullscreen: true\t\t\r\n});\r\n \r\nwindow.add(table);\r\nwindow.open();\r\n{code}", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-12-08T22:14:26.000+0000", "updated": "2015-12-08T22:15:27.000+0000" }, { "id": "372476", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "PR merged.\r\n\r\nAdding https://github.com/appcelerator/titanium_mobile/pull/7561 to update doc from `6.0.0` to `5.2.0`.", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2015-12-09T03:18:46.000+0000", "updated": "2015-12-09T03:18:46.000+0000" }, { "id": "372477", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "Doc PR merged.", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2015-12-09T03:33:50.000+0000", "updated": "2015-12-09T03:33:50.000+0000" }, { "id": "374627", "author": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "body": "Following are my observations I found while checking the fix:\r\nIf \"maxClassName\" is set to two more or less than the number of rows then the app crashes while scrolling up from the bottom.\r\nIf \"maxClassName\" is set to three or more than the number of rows then the app does not crash while scrolling up from the bottom.\r\n\r\nReopening\r\n\r\nTested on: 
iPhone 6s Plus Device (9.1)\r\n
Mac OSX El Capitan 10.11.2 (15C50)\r\n
Studio: 4.4.0.201511241829\r\nTi SDK: 5.2.0.v20160114021251\r\n
Appc NPM: 4.2.2
\r\nApp CLI: 5.2.0-224\r\nXcode 7.2
\r\nNode v4.2.4", "updateAuthor": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "created": "2016-01-15T00:18:19.000+0000", "updated": "2016-01-15T00:18:19.000+0000" }, { "id": "375664", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Josh, that is because we have some default class names mapping as well. Like I said, the use case for \"maxClassname\" is not practical in the scenario described above. You should only use 1 className per row UI, not row, for performance purposes.", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-02-01T23:52:35.000+0000", "updated": "2016-02-01T23:52:35.000+0000" }, { "id": "376070", "author": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "body": "The application is crashing still even without scrolling \r\n\r\n# Load the application\r\n# Rotate or open multitasking\r\n# the app crashes \r\n\r\n{code:javascript}\r\nvar section = Ti.UI.createTableViewSection();\r\nvar numberOfRows = 2; \r\nfor (var i=0; i < numberOfRows; i++) \r\n{ \r\n //fill section with rows \r\n section.add(Ti.UI.createTableViewRow({\r\n height: 50,\r\n width: Ti.UI.FILL,\r\n backgroundColor: 'white',\r\n color:'black',\r\n className: 'row' + i,\r\n title: 'row' + i\r\n }));\r\n};\r\n \r\nvar table = Ti.UI.createTableView({\r\n top: 0,\r\n left: 0,\r\n maxClassname: 3,\r\n height: Ti.UI.FILL,\r\n width: Ti.UI.FILL,\r\n data: [ section ]\r\n});\r\n \r\nvar window = Ti.UI.createWindow({\r\n fullscreen: true \r\n});\r\n \r\nwindow.add(table);\r\nwindow.open();\r\n\r\n{code}\r\n", "updateAuthor": { "name": "jlongton", "key": "jlongton", "displayName": "Josh Longton", "active": true, "timeZone": "Europe/London" }, "created": "2016-02-05T00:48:35.000+0000", "updated": "2016-02-05T00:53:41.000+0000" }, { "id": "376071", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "2 things. If the use case is not practical for \"maxClassname\" can we:\r\n1. Describe in documentation of the proper use of maxClassname\r\n2. fail elegantly instead of crashing if maxClassname is misused.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-02-05T01:16:44.000+0000", "updated": "2016-02-05T01:16:44.000+0000" }, { "id": "376263", "author": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Verified the fix.\r\n\r\nThere is no crash when {{maxClassName}} is is set to two more or less than the number of rows.\r\n\r\nClosing.\r\n\r\nEnvironment:\r\nAppc Studio : 4.5.0.201602070910\r\nTi SDK : 5.2.0.v20160208101502\r\nTi CLI : 5.0.6\r\nAlloy : 1.7.33\r\nMAC Yosemite : 10.10.5\r\nAppc NPM : 4.2.3-2\r\nAppc CLI : 5.2.0-249\r\nNode: 4.2.2\r\nNexus 5 - Android 5.1.1", "updateAuthor": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-02-08T19:52:23.000+0000", "updated": "2016-02-08T19:52:23.000+0000" } ], "maxResults": 19, "total": 19, "startAt": 0 } } }