0

I'm using a similar approach to the answer of this question. The only real difference is that instead of a SoftReference<Bitmap based cache, I'm saving the images to /data/data/my.app/files since they're not expected to change too often. My adapter's getView() function:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    //data from your adapter
    MyItem entry = getItem(position);
    //we want to reuse already constructed row views...
    if (convertView == null) {
        convertView = LayoutInflater.from(context).inflate(R.layout.appitem, null);
    }

    convertView.setTag(entry);

    TextView Name = (TextView)convertView.findViewById(R.id.Name);
    TextView Version = (TextView)convertView.findViewById(R.id.Version);
    final ImageView Icon = (ImageView)convertView.findViewById(R.id.Icon);

    Name.setText(entry.getName());
    Version.setText(entry.getVersion());
    Icon.setImageResource(R.drawable.default_icon); // the problem line

    try {
        final String _id = entry.getID();

        imageLoader.loadImage(_id, "<my url>", new ImageThreadLoader.ImageLoadedListener() {
            public void imageLoaded(Bitmap imageBitmap) {
                Icon.setImageBitmap(imageBitmap);
                notifyDataSetChanged();
            }
        });
    } catch (Throwable t) {
        Log.e("","", t); // nothing is hitting this log
    }

    return convertView;
}

The marked "problem line" above where I set the icon to a default icon, if I remove that line then things mostly work ok (when Views are reused it'll display the old image shortly before showing the new one). If that line is present then the image never changes to anything else. The anonymous ImageLoadedListener is still run on the UI thread and setting a breakpoint there reveals everything seems to be happening normally. I also know that the ImageThreadLoader is working correctly. The files appear where they should and look just fine (and they load fine when the problem line above is removed).

Why would setting the image ahead of time result in not being able to update it later?

Community
  • 1
  • 1
Corey Ogburn
  • 24,072
  • 31
  • 113
  • 188
  • #1 add a try-catch *inside* the imageLoaded(Bitmap) and log the imageBitmap value (==null?) – Loda Oct 30 '13 at 16:11
  • Added a try/catch. Nothing was thrown. In my debugging of this, it's also never returned null. – Corey Ogburn Oct 30 '13 at 16:13
  • you cannot "debug" (ie: with debugger) a problem related to thread and changing UI element. The most likly output, is that it will work with the debugger, but not without. use Log.e(). – Loda Oct 30 '13 at 16:31
  • http://stackoverflow.com/questions/19635220/listview-not-refreshing-already-visible-items seems like notifyDataSetChanged not working for visible items if data did not changed – Selvin Oct 30 '13 at 16:33
  • @Selvin: So it should work if I move the visible items off screen and move them back on? Because that doesn't happen. – Corey Ogburn Oct 30 '13 at 16:36

1 Answers1

2

a hunch:

remove the notifyDataSetChanged().

Why? the call adapter.notifyDataSetChanged() will provoqc a FULL refresh of the list (ie: of each view). And so, a new call for each item to getView(position). In this call you change again the image to default_icon. This append JUST AFTER setting the good one!

so the sequence is: set default_icon for one image, load one image from disk, invalidate -> set default for ALL, load one image from disk, ....

EDIT: clarify explanation, remove assumption about thread limit.

Loda
  • 1,970
  • 2
  • 20
  • 40
  • Head/Thread limit? I'm not sure I follow. The implementation does not start 1 thread per list item, it just adds to a queue that 1 thread handles. Regardless, removing notifyDataSetChanged does mysteriously seem to work. – Corey Ogburn Oct 30 '13 at 16:40
  • I did not know the implementation of imageLoader, I just saw "new xxxThreadxx()" – Loda Oct 30 '13 at 16:42
  • It's essentially a Queue and a synchronized block running on a single thread. I'm still very surprised that removing the notify made it work. Oh well. – Corey Ogburn Oct 30 '13 at 16:48