Reputation: 1433
I have a Lazy adapter that add the title, subtitle, and picture to a ListView. Lately I have been noticing in my ListView that my images are being duplicated.
Here is where I add my array to the adapter
protected void onPostExecute(String result) {
LazyAdapter adapter = new LazyAdapter(Services.this,menuItems);
serviceList.setAdapter(adapter);
}
Here is where I call the async method to add my image (its a url thats why it is in a async method)
vi.findViewById(R.id.thumbnail).setVisibility(View.VISIBLE);
title.setText(items.get("title")); // Set Title
listData.setText(items.get("htmlcontent")); // Set content
thumb_image.setBackgroundResource(R.layout.serviceborder);//Adds border
new setLogoImage(thumb_image).execute(); // Async Method call
And here is where I set my bitmap image
private class setLogoImage extends AsyncTask<Object, Void, Bitmap> {
private ImageView imv;
public setLogoImage(ImageView imv) {
this.imv = imv;
}
@Override
protected Bitmap doInBackground(Object... params) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream((InputStream)new URL(items.get("thumburl")).getContent());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
imv.setImageBitmap(Bitmap.createScaledBitmap(result, 50, 50, false));
}
}
The items
variable is a HashMap that stores my info. I get the position of the data given to the adapter and assign it to the items HashMap. Like so:
items = new HashMap<String, String>();
items = data.get(position);
This happens randomly, it seems, and it gets annoying to see the wrong picture there about 30% of the time, especially when I'm trying to debug.
Any help would be great. Thanks
Here is an image to see what is happening
Upvotes: 1
Views: 330
Reputation: 39698
Any time you have something that happens randomly, and you have any kind of a thread, you should think two works, Race Condition. Basically, your AsyncTasks are all loading the same image. They should be passed in the value to load. I noticed you aren't doing anything with params. I'm not sure exactly what you should do, but the problem is somewhere in your AsyncTask.
@Override
protected Bitmap doInBackground(Object... params) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream((InputStream)new URL(items.get("thumburl")).getContent());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
You should probably pass in the URL (Or the string it represents). In this example, I pass in the URL, but feel free to change it around how you want. The key thing is, you should pass a representation of the image location into the function, rather than try to figure out what image to use when you are in the function.
new setLogoImage(new Url(items.get("thumburl"))).execute(); // Async Method call
@Override
protected Bitmap doInBackground(Url... input) {
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream((InputStream)input[0]).getContent());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
Upvotes: 1