[TIMOB-17674] Android: On Android Ti.UI.ImageView can show the wrong image (cache bug, explained)
GitHub Issue | n/a |
---|---|
Type | Improvement |
Priority | None |
Status | Open |
Resolution | Unresolved |
Affected Version/s | Release 3.3.0 |
Fix Version/s | n/a |
Components | Android |
Labels | Android, ImageView, TCSupport |
Reporter | Szymon Tomasz Stefanek |
Assignee | Unknown |
Created | 2014-09-10T19:40:16.000+0000 |
Updated | 2018-02-28T20:04:10.000+0000 |
Description
If an application has two different images with urls/paths that map to the same hash code at java.lang.String level then Ti.UI.ImageView can show the wrong one.
TiUIImageView internally uses a memory cache for the Bitmaps with TiDrawableReference.hashCode() as keys. In case of an url-based drawable reference TiDrawableReference.hashCode() turns into a simple java.lang.String.hashCode(url) wrapper.
See line 115 of
https://github.com/appcelerator/titanium_mobile/blob/master/android/titanium/src/java/org/appcelerator/titanium/view/TiDrawableReference.java
and line 694 of
https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/ui/src/java/ti/modules/titanium/ui/widget/TiUIImageView.java
java.lang.String.hashCode() is very likely to generate collisions.
The following code prints the same number for both urls.
public static void main(String[] args)
{
int h1 = "file:///data/data/it.xenesys.Nomination/app_appdata/ITEMFASHION_0002TW1.png".hashCode();
int h2 = "file:///data/data/it.xenesys.Nomination/app_appdata/ITEMFASHION_0002TVP.png".hashCode();
System.out.println("Hash code 1: " + Integer.toString(h1));
System.out.println("Hash code 2: " + Integer.toString(h2));
}
The cache should use a stronger hashing algorithm (such as SHA1) and possibly add more data to be hashed (the file size?).
This also happens with BLOB type images sometimes. If you build a gallery from the mediastore (MICRO_KIND blobs) with lots of imageviews, you falsely hit the cach very quickly.