[TIMOB-14777] Android: NullPointerException on ListView + ImageView
GitHub Issue | n/a |
---|---|
Type | Bug |
Priority | High |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2013-10-28T23:23:03.000+0000 |
Affected Version/s | Release 3.1.1 |
Fix Version/s | 2013 Sprint 18, 2013 Sprint 18 API, Release 3.1.3, Release 3.2.0 |
Components | Android |
Labels | android, crash, imageview, listview, nullpointerexception, triage |
Reporter | Danny Leshem |
Assignee | Hieu Pham |
Created | 2013-08-05T13:10:19.000+0000 |
Updated | 2013-10-28T23:23:03.000+0000 |
Description
Application would sometimes crash (NPE) when aggressively scrolling a ListView with remote images.
Seems there were some safety checks missing in the code (although they were used elsewhere in the same class). Added the safety checks as needed.
Testing code:
var section = Ti.UI.createListSection({footerTitle: "Footer 1"});
var data = [];
for (var i = 0; i < 40; i++) {
var builtInRow = {
properties: {
height: '150dp',
title: "Label " + i,
image: null,
accessoryType: 3
}
};
if (i == 5) {
builtInRow.properties.image = 'https://g.twimg.com/business/page/image/11TwitterForSmallBusiness-300_1.png';
} else if (i == 10) {
builtInRow.properties.image = 'http://static.appcelerator.com/images/header/appc_logo.png';
} else if (i == 15) {
builtInRow.properties.image = 'http://www.seobook.com/images/smallfish.jpg';
} else if (i == 20) {
builtInRow.properties.image = 'http://www.newyorker.com/online/blogs/photobooth/NASAEarth-01.jpg';
} else if (i == 25) {
builtInRow.properties.image = 'http://www.wallcg.com/images/2013/02/nature-fond-ecran-image-arriere-plan-hd-29-hd.jpg';
}
data.push(builtInRow);
}
section.setItems(data);
var listView = Ti.UI.createListView({backgroundColor: "white", sections: [section]});
var win = Ti.UI.createWindow({fullscreen: false, backgroundColor: 'red'});
win.add(listView);
win.open();
1. Run code
2. Scroll aggressively. App should not crash.
Hi Danny, Thanks 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. Cheers.
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. The fix simply adds 2 (XXX != null) checks, whose necessity would be immediately apparent to whoever maintains this class.
Some additional data regarding the issue- The 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. A 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. The pull request does not completely solve the issue. Specifically, a NPE can still be thrown in TiUIImageView$2.loadImageFinished(TiUIImageView.java:140) because if (imgsrc != null) but (imgsrc.getUrl() == null) then TiUrl.getCleanUri(imgsrc.getUrl()).toString() is wrong.
I'm seeing a NPE in the same place as Danny in my app (TiUIImageView.java:140). In 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. The crash isn't 100%, but happens maybe 10% of the time. It must be a timing thing for my scenario. Here's the exception: E/TiApplication( 829): java.lang.NullPointerException E/TiApplication( 829): at ti.modules.titanium.ui.widget.TiUIImageView$2.loadImageFinished(TiUIImageView.java:140) E/TiApplication( 829): at org.appcelerator.titanium.util.TiLoadImageManager.handleLoadImageMessage(TiLoadImageManager.java:90) E/TiApplication( 829): at org.appcelerator.titanium.util.TiLoadImageManager.handleMessage(TiLoadImageManager.java:107) E/TiApplication( 829): at android.os.Handler.dispatchMessage(Handler.java:95) E/TiApplication( 829): at android.os.Looper.loop(Looper.java:137) E/TiApplication( 829): at android.app.ActivityThread.main(ActivityThread.java:4745) E/TiApplication( 829): at java.lang.reflect.Method.invokeNative(Native Method) E/TiApplication( 829): at java.lang.reflect.Method.invoke(Method.java:511) E/TiApplication( 829): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) E/TiApplication( 829): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) E/TiApplication( 829): at dalvik.system.NativeStart.main(Native Method) 3.1.2.GA
Hi All, Can 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.
[~dleshem] Can you provide a test case?
Sorry, [~ingo]... hard to extract a test case from our implementation. It should be pretty easy to reproduce though, see my last comment.
I'm unable to reproduce this issue using a listview with images set to null and remote images. Which devices did you tested with?
[~hpham] - Galaxy S4 (Android 4.2.2) and Galaxy S1 (Android 2.3.6)
master PR: https://github.com/appcelerator/titanium_mobile/pull/4653
3.1.X PR: https://github.com/appcelerator/titanium_mobile/pull/4657
Cannot reproduce the issue, tested on HTC One (2.3.6) and Nexus Galaxy (4.2.2) TiSDK: 3.1.3.v20130913121549 CLI 3.1.2 GA Appceleator Studio 3.1.3.201309132456 Closing.
Reopening to remove labels