{ "id": "77690", "key": "TIMOB-4640", "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": "11363", "description": "Mobile 1.8.0 M10", "name": "Sprint 2011-31", "archived": true, "released": true, "releaseDate": "2011-08-08" }, { "id": "11331", "description": "", "name": "Release 1.8.0", "archived": true, "released": true, "releaseDate": "2011-10-31" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2011-08-05T15:24:46.000+0000", "created": "2011-07-11T12:44:55.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [], "versions": [ { "id": "11367", "description": "", "name": "Release 1.7.1", "archived": true, "released": true, "releaseDate": "2011-06-21" } ], "issuelinks": [ { "id": "12060", "type": { "id": "10000", "name": "Blocks", "inward": "is blocked by", "outward": "blocks" }, "outwardIssue": { "id": "78817", "key": "TIMOB-4917", "fields": { "summary": "iOS: change Table View appendRow to support an array of rows or row data", "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": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false } } } }, { "id": "12059", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "78816", "key": "TIMOB-4916", "fields": { "summary": "Android: change Table View appendRow to support an array of rows or row data", "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": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false } } } } ], "assignee": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "updated": "2014-06-19T12:46:25.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": "h3. Problem:\r\nPopulating a table view with complex rows makes the entire Android UI very unresponsive until the rows are all loaded making the app unusable\r\n\r\nh3. Tests\r\n1. *Test 1* One tab will load the first 10 rows in an array and populate the table view. After that, the nex 400+ rows will load on the table one by one. At this point the device is almost locked and nothing can be done.\r\n2. *Test 2* On this other tab, I download the JSON, create an array of rows, and after, populate the table view with the array.\r\n\r\nTest 2 would work, but populating the table view with so many rows, it takes too long.\r\n\r\nh3. To reproduce:\r\n1. Run the app. On tab1 hit the menu button and click on \"Start Downloading\" A loading indicator will appear and disappear after the download is completed. Then, the first 10 rows will appear and the next 400+ rows will start populating the table view. At this point the UI is almost locked up, everything is very slow.\r\n2. Click on tab2 and hit the menu button and then on \"Start Downloading\" This one takes longer for the rows to appear, so test1 would be a better solution from a user stand-point.\r\n\r\nh3. The Code:\r\n{code:title=\"app.js\"}\r\n\r\nvar tabGroup = Ti.UI.createTabGroup();\r\n\r\nvar win1 = Ti.UI.createWindow({\r\n\turl:'win1.js'\r\n});\r\nvar win2 = Ti.UI.createWindow({\r\n\turl:'win2.js'\r\n});\r\n\r\nvar tab1 = Ti.UI.createTab({\r\n\twindow:win1,\r\n\ttitle:'Test 1'\r\n});\r\nvar tab2 = Ti.UI.createTab({\r\n\twindow:win2,\r\n\ttitle:'test 2'\r\n});\r\n\r\ntabGroup.addTab(tab1);\r\ntabGroup.addTab(tab2);\r\n\r\ntabGroup.open();\r\n{code}\r\n{code:title=\"win1.js\"}\r\n\r\nvar win = Ti.UI.currentWindow;\r\nwin.backgroundColor='#fff';\r\nvar xhr = Ti.Network.createHTTPClient();\r\n\r\nvar tableView = Ti.UI.createTableView();\r\nwin.add(tableView);\r\n\r\nvar act = Ti.UI.createActivityIndicator({\r\n\tmessage:'Downloading...'\r\n});\r\n\r\nfunction customRow(a){\r\n\ta = a || {};\r\n\ta.image = a.pic_square || '';\r\n\ta.name = a.name || '';\r\n\ta.id = a.uid || '';\r\n\t\r\n\tvar img = Ti.UI.createImageView({\r\n\t\timage:a.image,\r\n\t\twidth:80,\r\n\t\tleft:10\r\n\t});\r\n\tvar label = Ti.UI.createLabel({\r\n\t\tleft:100,\r\n\t\ttop:10,\r\n\t\tbottom:10,\r\n\t\ttext:a.name\r\n\t});\r\n\tvar row = Ti.UI.createTableViewRow({\r\n\t\trowId:a.id,\r\n\t\tclassName:'custom_row'\r\n\t});\r\n\trow.add(img);\r\n\trow.add(label);\r\n\t\r\n\treturn row;\r\n}\r\n\r\nxhr.onload = function(){\r\n\tact.hide();\r\n\tTi.API.info('loading......');\r\n\tvar startTime = new Date().getTime();\r\n\tvar json = JSON.parse(this.responseText);\r\n\t\r\n\tvar initData = [];\r\n\tfor(var i = 0; i < 9;i++){\r\n\t\tinitData.push(\r\n\t\t\tcustomRow(json[i])\r\n\t\t);\r\n\t}\r\n\ttableView.data = initData;\r\n\t\r\n\t// this is how long it too for the rows to be displayed\r\n\talert(new Date().getTime()-startTime);\r\n\tfor(var i = 9; i < json.length;i++){\r\n\t\ttableView.appendRow(customRow(json[i]));\r\n\t}\r\n}\r\n\r\nxhr.open('GET', 'http://jwtdigital.co.il/tools/tmp/json_data.php');\r\n\r\nwin.activity.onCreateOptionsMenu = function(e) {\r\n\tvar menu = e.menu;\r\n\r\n\tvar m1 = menu.add({ title : 'Start Download' });\r\n\tm1.addEventListener('click', function(e) {\r\n\t\tact.show();\r\n\t\txhr.send();\r\n\t});\r\n};\r\n{code}\r\n{code:title=\"win2.js\"}\r\nvar win = Ti.UI.currentWindow;\r\nwin.backgroundColor='#fff';\r\n\r\nvar xhr = Ti.Network.createHTTPClient();\r\n\r\nvar tableView = Ti.UI.createTableView();\r\nwin.add(tableView);\r\n\r\nvar act = Ti.UI.createActivityIndicator({\r\n\tmessage:'Downloading...'\r\n});\r\n\r\nfunction customRow(a){\r\n\ta = a || {};\r\n\ta.image = a.pic_square || '';\r\n\ta.name = a.name || '';\r\n\ta.id = a.uid || '';\r\n\tvar img = Ti.UI.createImageView({\r\n\t\timage:a.image,\r\n\t\twidth:80,\r\n\t\tleft:10\r\n\t});\r\n\tvar label = Ti.UI.createLabel({\r\n\t\tleft:100,\r\n\t\ttop:10,\r\n\t\tbottom:10,\r\n\t\ttext:a.name\r\n\t});\r\n\tvar row = Ti.UI.createTableViewRow({\r\n\t\trowId:a.id\r\n\t});\r\n\trow.add(img);\r\n\trow.add(label);\r\n\t\r\n\treturn row;\r\n}\r\n\r\nxhr.onload = function(){\r\n\tact.hide();\r\n\tTi.API.info('loading......');\r\n\tvar startTime = new Date().getTime();\r\n\tvar json = JSON.parse(this.responseText);\r\n\t\r\n\tvar initData = [];\r\n\tfor(var i = 0; i < json.length;i++){\r\n\t\tinitData.push(\r\n\t\t\tcustomRow(json[i])\r\n\t\t);\r\n\t\tTi.API.info(i);\r\n\t}\r\n\ttableView.data = initData;\r\n\t\r\n\t// this is how long it too for the rows to be displayed\r\n\talert(new Date().getTime()-startTime);\r\n}\r\n\r\nxhr.open('GET', 'http://jwtdigital.co.il/tools/tmp/json_data.php');\r\n\r\nwin.activity.onCreateOptionsMenu = function(e) {\r\n\tvar menu = e.menu;\r\n\r\n\tvar m1 = menu.add({ title : 'Start Download' });\r\n\tm1.addEventListener('click', function(e) {\r\n\t\tact.show();\r\n\t\txhr.send();\r\n\t});\r\n};\r\n{code}\r\nh3. Associated Helpdesk Ticket:\r\nAGM-15481-948\r\n\r\nAttached is a zip with the files.", "attachment": [ { "id": "22246", "filename": "app.zip", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-08-05T14:25:29.000+0000", "size": 1637, "mimeType": "application/zip" }, { "id": "22616", "filename": "builder.js", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-08-19T23:19:07.000+0000", "size": 1180, "mimeType": "application/x-javascript" }, { "id": "21785", "filename": "Resources.zip", "author": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2011-07-11T12:44:55.000+0000", "size": 35761, "mimeType": "application/zip" } ], "flagged": false, "summary": "Android: UI unresponsive when populating Table Views", "creator": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "environment": "Android Emulator\r\nMotorola Droid\r\nAPIs 2.2", "comment": { "comments": [ { "id": "159790", "author": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Triage and try to have appendRow accept an array of items to see if the performance boost is significant.", "updateAuthor": { "name": "dthorp", "key": "dthorp", "displayName": "Don Thorp", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-07-18T10:22:22.000+0000", "updated": "2011-07-18T10:22:22.000+0000" }, { "id": "162040", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "In the future, there will be a new list view style implementation that will make dealing with these issues much easier. It is also planned that 1.8 will include worker threads which will allow further options in increasing performance for operations like this. In the mean time, I have attached a working example that shows a way of handling the loading in the background for the most part without affecting the UI responsiveness. The tab 2 example, shows the new approach.", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-08-05T14:24:53.000+0000", "updated": "2011-08-05T14:24:53.000+0000" }, { "id": "162042", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "work around for loading table data in the background", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-08-05T14:25:29.000+0000", "updated": "2011-08-05T14:25:29.000+0000" }, { "id": "162052", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "create new tickets to support appendRow being allowed to take an array of rows rather than just a single row / row data\r\nAndroid: 4916\r\niOS: 4917", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-08-05T15:20:26.000+0000", "updated": "2011-08-05T15:20:26.000+0000" }, { "id": "163546", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "Attaching missing builder.js file required by test in the previously attached app.zip", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-08-19T23:19:07.000+0000", "updated": "2011-08-19T23:19:07.000+0000" }, { "id": "163547", "author": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "body": "To run test, follow the above instructions but first grab the attached builder.js and drop it in the resources directory along with app.js", "updateAuthor": { "name": "opiecyrus", "key": "opiecyrus", "displayName": "Opie Cyrus", "active": true, "timeZone": "America/Chicago" }, "created": "2011-08-19T23:20:30.000+0000", "updated": "2011-08-19T23:20:30.000+0000" }, { "id": "164052", "author": { "name": "nhuynh", "key": "nhuynh", "displayName": "Natalie Huynh", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Tested with 1.8.0.v20110819142548\nMotorola Xoom 3.2\nNexus One 2.2.2", "updateAuthor": { "name": "nhuynh", "key": "nhuynh", "displayName": "Natalie Huynh", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2011-08-25T13:14:57.000+0000", "updated": "2011-08-25T13:14:57.000+0000" } ], "maxResults": 8, "total": 8, "startAt": 0 } } }