{ "id": "117986", "key": "TIMOB-14777", "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": "15646", "description": "2013 Sprint 18", "name": "2013 Sprint 18", "archived": true, "released": true, "releaseDate": "2013-09-06" }, { "id": "15690", "description": "2013 Sprint 18 API", "name": "2013 Sprint 18 API", "archived": true, "released": true, "releaseDate": "2013-09-06" }, { "id": "15593", "description": "Release 3.1.3", "name": "Release 3.1.3", "archived": true, "released": true, "releaseDate": "2013-09-18" }, { "id": "14982", "description": "Release 3.2.0", "name": "Release 3.2.0", "archived": false, "released": true, "releaseDate": "2013-12-19" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2013-10-28T23:23:03.000+0000", "created": "2013-08-05T13:10:19.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "android", "crash", "imageview", "listview", "nullpointerexception", "triage" ], "versions": [ { "id": "15478", "description": "Release 3.1.1", "name": "Release 3.1.1", "archived": true, "released": true, "releaseDate": "2013-06-17" } ], "issuelinks": [ { "id": "32008", "type": { "id": "10122", "name": "Gantt: start-finish", "inward": "is triggered by", "outward": "is triggering" }, "outwardIssue": { "id": "119984", "key": "TIMOB-15200", "fields": { "summary": "Android: ImageView.image from XHR no longer shows new image", "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": "Critical", "id": "1" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } }, { "id": "32415", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "120990", "key": "TIMOB-15439", "fields": { "summary": "Android: App crashes with just a few ImageViews", "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 } } } } ], "assignee": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2013-10-28T23:23:03.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": "Application would sometimes crash (NPE) when aggressively scrolling a ListView with remote images.\r\n\r\nSeems there were some safety checks missing in the code (although they were used elsewhere in the same class). Added the safety checks as needed.\r\n\r\nTesting code: \r\n{code}\r\nvar section = Ti.UI.createListSection({footerTitle: \"Footer 1\"});\r\n\r\nvar data = [];\r\nfor (var i = 0; i < 40; i++) {\r\n\r\n var builtInRow = {\r\n \tproperties: {\r\n \theight: '150dp',\r\n\t\ttitle: \"Label \" + i, \r\n\t\timage: null,\r\n\t\taccessoryType: 3\r\n\t\t} \r\n\t};\r\n\t\r\n\tif (i == 5) {\r\n\t builtInRow.properties.image = 'https://g.twimg.com/business/page/image/11TwitterForSmallBusiness-300_1.png';\r\n\t} else if (i == 10) {\r\n\t builtInRow.properties.image = 'http://static.appcelerator.com/images/header/appc_logo.png';\r\n\t} else if (i == 15) {\r\n\t builtInRow.properties.image = 'http://www.seobook.com/images/smallfish.jpg';\r\n\t} else if (i == 20) {\r\n\t builtInRow.properties.image = 'http://www.newyorker.com/online/blogs/photobooth/NASAEarth-01.jpg';\r\n\t} else if (i == 25) {\r\n\t builtInRow.properties.image = 'http://www.wallcg.com/images/2013/02/nature-fond-ecran-image-arriere-plan-hd-29-hd.jpg';\r\n\t}\r\n\tdata.push(builtInRow);\r\n\t\r\n}\r\nsection.setItems(data);\r\n\r\n\r\nvar listView = Ti.UI.createListView({backgroundColor: \"white\", sections: [section]});\r\n\r\nvar win = Ti.UI.createWindow({fullscreen: false, backgroundColor: 'red'});\r\n\r\nwin.add(listView);\r\n\r\nwin.open();\r\n{code}\r\n\r\n1. Run code\r\n2. Scroll aggressively. App should not crash.", "attachment": [], "flagged": false, "summary": "Android: NullPointerException on ListView + ImageView", "creator": { "name": "dleshem", "key": "dleshem", "displayName": "Danny Leshem", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "dleshem", "key": "dleshem", "displayName": "Danny Leshem", "active": true, "timeZone": "America/Los_Angeles" }, "environment": "OS: Android (any)\r\nSDK: 3.1.1", "comment": { "comments": [ { "id": "265219", "author": { "name": "dsefton", "key": "dsefton", "displayName": "Daniel Sefton", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Hi Danny,\r\n\r\nThanks for the pull request. Do you happen to be able to create a reproducible test case that we can drop into an app.js and run? It will help us pass through and test the pull request.\r\n\r\nCheers.", "updateAuthor": { "name": "dsefton", "key": "dsefton", "displayName": "Daniel Sefton", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-08-06T21:58:18.000+0000", "updated": "2013-08-06T21:58:18.000+0000" }, { "id": "265304", "author": { "name": "dleshem", "key": "dleshem", "displayName": "Danny Leshem", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Sorry, no time to create a test case. I think (but not certain) that the bug manifests itself in ListViews where some ImageViews have the image property set to null. Only on Android, of course.\r\n\r\nThe fix simply adds 2 (XXX != null) checks, whose necessity would be immediately apparent to whoever maintains this class.", "updateAuthor": { "name": "dleshem", "key": "dleshem", "displayName": "Danny Leshem", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-08-07T08:04:53.000+0000", "updated": "2013-08-07T08:05:27.000+0000" }, { "id": "265363", "author": { "name": "dleshem", "key": "dleshem", "displayName": "Danny Leshem", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Some additional data regarding the issue-\r\n\r\nThe issue is definitely triggered when a ListView's item template includes an ImageView, and when some items set its \"image\" field to null while others set it to a remote image URL. In this case, aggressively scrolling back and forth on Android causes a NullPointerException that crashes the app.\r\n\r\nA workaround is to never have the image field set to null. Instead, to point it to some remote image URL (e.g. a single pixel image) and simply toggle the \"visible\" field.\r\n\r\nThe pull request does not completely solve the issue. Specifically, a NPE can still be thrown in\r\nTiUIImageView$2.loadImageFinished(TiUIImageView.java:140)\r\n\r\nbecause if (imgsrc != null) but (imgsrc.getUrl() == null) then\r\nTiUrl.getCleanUri(imgsrc.getUrl()).toString()\r\nis wrong.", "updateAuthor": { "name": "dleshem", "key": "dleshem", "displayName": "Danny Leshem", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-08-07T17:24:46.000+0000", "updated": "2013-08-07T17:24:46.000+0000" }, { "id": "268921", "author": { "name": "nicjansma", "key": "nicjansma", "displayName": "Nic Jansma", "active": true, "timeZone": "America/Havana" }, "body": "I'm seeing a NPE in the same place as Danny in my app (TiUIImageView.java:140).\r\n\r\nIn my case, I always have the ImageView.image field set as a placeholder image on the file system. Then I fetch new images (via XHR) from the internet and set the ImageView.image.\r\n\r\nThe crash isn't 100%, but happens maybe 10% of the time. It must be a timing thing for my scenario.\r\n\r\nHere's the exception:\r\n\r\nE/TiApplication( 829): java.lang.NullPointerException\r\nE/TiApplication( 829): at ti.modules.titanium.ui.widget.TiUIImageView$2.loadImageFinished(TiUIImageView.java:140)\r\nE/TiApplication( 829): at org.appcelerator.titanium.util.TiLoadImageManager.handleLoadImageMessage(TiLoadImageManager.java:90)\r\nE/TiApplication( 829): at org.appcelerator.titanium.util.TiLoadImageManager.handleMessage(TiLoadImageManager.java:107)\r\nE/TiApplication( 829): at android.os.Handler.dispatchMessage(Handler.java:95)\r\nE/TiApplication( 829): at android.os.Looper.loop(Looper.java:137)\r\nE/TiApplication( 829): at android.app.ActivityThread.main(ActivityThread.java:4745)\r\nE/TiApplication( 829): at java.lang.reflect.Method.invokeNative(Native Method)\r\nE/TiApplication( 829): at java.lang.reflect.Method.invoke(Method.java:511)\r\nE/TiApplication( 829): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)\r\nE/TiApplication( 829): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)\r\nE/TiApplication( 829): at dalvik.system.NativeStart.main(Native Method)\r\n\r\n3.1.2.GA", "updateAuthor": { "name": "nicjansma", "key": "nicjansma", "displayName": "Nic Jansma", "active": true, "timeZone": "America/Havana" }, "created": "2013-08-29T18:58:36.000+0000", "updated": "2013-08-29T18:58:36.000+0000" }, { "id": "269053", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Hi All,\r\n\r\nCan anyone submit a test case or piece of sample code? The fix looks safe, but we want to be able to confirm we fixed it on our side.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-08-30T16:49:24.000+0000", "updated": "2013-08-30T16:49:24.000+0000" }, { "id": "269322", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~dleshem] Can you provide a test case?", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-09-03T18:22:54.000+0000", "updated": "2013-09-03T18:22:54.000+0000" }, { "id": "269333", "author": { "name": "dleshem", "key": "dleshem", "displayName": "Danny Leshem", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Sorry, [~ingo]... hard to extract a test case from our implementation.\r\nIt should be pretty easy to reproduce though, see my last comment.", "updateAuthor": { "name": "dleshem", "key": "dleshem", "displayName": "Danny Leshem", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-09-03T18:59:50.000+0000", "updated": "2013-09-03T18:59:50.000+0000" }, { "id": "269660", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "I'm unable to reproduce this issue using a listview with images set to null and remote images. Which devices did you tested with?", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-09-05T01:08:34.000+0000", "updated": "2013-09-05T01:08:34.000+0000" }, { "id": "269817", "author": { "name": "dleshem", "key": "dleshem", "displayName": "Danny Leshem", "active": true, "timeZone": "America/Los_Angeles" }, "body": "[~hpham] - Galaxy S4 (Android 4.2.2) and Galaxy S1 (Android 2.3.6)", "updateAuthor": { "name": "dleshem", "key": "dleshem", "displayName": "Danny Leshem", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-09-05T20:55:59.000+0000", "updated": "2013-09-05T20:55:59.000+0000" }, { "id": "269854", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "master PR: https://github.com/appcelerator/titanium_mobile/pull/4653", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-09-05T22:52:42.000+0000", "updated": "2013-09-05T22:52:42.000+0000" }, { "id": "270026", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "3.1.X PR: https://github.com/appcelerator/titanium_mobile/pull/4657", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-09-06T20:12:36.000+0000", "updated": "2013-09-06T20:12:36.000+0000" }, { "id": "271128", "author": { "name": "fcasali", "key": "fcasali", "displayName": "Federico Casali", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Cannot reproduce the issue, tested on HTC One (2.3.6) and Nexus Galaxy (4.2.2)\nTiSDK: 3.1.3.v20130913121549 \nCLI 3.1.2 GA\nAppceleator Studio 3.1.3.201309132456\n\nClosing.", "updateAuthor": { "name": "fcasali", "key": "fcasali", "displayName": "Federico Casali", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-09-13T22:28:46.000+0000", "updated": "2013-09-13T22:28:46.000+0000" }, { "id": "277063", "author": { "name": "ayeung", "key": "ayeung", "displayName": "Allen Yeung", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Reopening to remove labels\r\n", "updateAuthor": { "name": "ayeung", "key": "ayeung", "displayName": "Allen Yeung", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-10-28T23:22:49.000+0000", "updated": "2013-10-28T23:22:49.000+0000" } ], "maxResults": 14, "total": 14, "startAt": 0 } } }