Using Asynctask to Load Images in Listview

Using AsyncTask to load Images in ListView

You can send in the ImageView to the task constructor and keep a reference to the image path there. Now at onPostExecute, check if the current tag of the ImageView is the same as the one that you started with. If yes, then set the image. If no, don't do anything.

However, this means that the image will be downloaded in any case. You'll just not set the wrong image on the view.

EDIT:
First pass the ImageView to the task constructor:

new LoadImage(imageView).execute()

Then save a reference to the ImageView and image path in LoadImage constructor. It is important to save the path in the constructor and not in doInBackground to ensure that we don't run into multi threading problems. Then at onPostExecute we check the current path.

class LoadImage extends AsyncTask<Object, Void, Bitmap>{

private ImageView imv;
private String path;

public LoadImage(ImageView imv) {
this.imv = imv;
this.path = imv.getTag().toString();
}

@Override
protected Bitmap doInBackground(Object... params) {
Bitmap bitmap = null;
File file = new File(
Environment.getExternalStorageDirectory().getAbsolutePath() + path);

if(file.exists()){
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
}

return bitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
if (!imv.getTag().toString().equals(path)) {
/* The path is not same. This means that this
image view is handled by some other async task.
We don't do anything and return. */
return;
}

if(result != null && imv != null){
imv.setVisibility(View.VISIBLE);
imv.setImageBitmap(result);
}else{
imv.setVisibility(View.GONE);
}
}

}

Using AsyncTask to load images into a adapter for ListView

Your view object in the Async task is never initialized, atleast I don't see that code. What I think you could do is launch a new AsyncTask for every "new" view you're creating in your adapter. You would need to make the async task have a reference to the imageview you want to populate though. One way to do this is like this.

public class ImageLoader extends AsyncTask<Object, String, Bitmap> {

private WeakReference<ImageView> mReference;
private View view;
private Bitmap bitmap = null;
public static BitmapDrawable drawable = null;
Context context;
Cursor cursor;
long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));

public ImageLoader(ImageView imageView) {
mReference = new WeakReference<ImageView>(imageView);
}

@Override
protected Bitmap doInBackground(Object... parameters) { ... your code }

@Override
protected Void onPostExecute(Bitmap bitmap) {
if(mReference != null) {
if(bitmap != null) {
ImageView view = mReference.get();
// note that this could still return null if the view or the reference has been
// garbage collected which it could be since it is a weak reference, so you should
// always check the status in this case.

//do what you want with the image view.
}
}
}

then in your adapter do something like this.

public class SongAdapter extends CursorAdapter implements SectionIndexer{

...other code...

@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView title1 = (TextView) view.findViewById(R.id.titlelist);
TextView artist1 = (TextView) view.findViewById(R.id.artistlist);
ImageView album1 = (ImageView) view.findViewById(R.id.iconlist);

String title = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
String artist = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
String album = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
long albumId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));
StringBuilder titleBuild = new StringBuilder();
titleBuild.append(title);
if(titleBuild.length() > 35)
{
titleBuild.setLength(32);
title = titleBuild.toString()+"...";
}
else
{
title = titleBuild.toString();
}
StringBuilder artistBuild = new StringBuilder();
artistBuild.append(artist);
if(artistBuild.length() > 35)
{
artistBuild.setLength(32);
artist = artistBuild.toString()+"...";
}
else
{
artist = artistBuild.toString();
}



<---->
// new code
new ImageLoader(album1).execute();

// old code album1.setImageDrawable(ImageLoader.drawable);
title1.setText(title);
artist1.setText(artist);
}

}

I've used a similar technique in a grid view and it's cool because you can actually see each image view being populated.

Hope that helps!

I wanna learn how to load images in Asynctask way and load those in listViewAdapter

If I were you I would use that list adapter but within it use the picasso library to load the image. Picasso does not load images on the UI thread. That is why you are receiving this error. After adding the library, try making your getView() like so:

@Override
public View getView(int position, View convertView, ViewGroup parent) {

if(convertView == null) {
convertView = inflater.inflate(R.layout.item_pic, null);
holder = new ViewHolder();
holder.imageView = (ImageView) convertView.findViewById(R.id.img_pic);
holder.textView = (TextView) convertView.findViewById(R.id.txt_pic);
convertView.setTag(holder);

}else {
holder = (ViewHolder) convertView.getTag();
}
int resID = (Integer) list.get(position).get("image");
String text = (String) list.get(position).get("text");
//Picasso code
Picasso.Builder builder = new Picasso.Builder(context);
Picasso picasso = builder.build();
picasso.load(resID).into(holder.imageView);
//End Picasso code
holder.textView.setText(text);
notifyDataSetChanged();
return convertView;
}

Display Image in Listview with AsyncTask

Why do you need AsyncTask? Try to use library Picasso and open images by one string:

File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + path);
Picasso.with(context).load(file).into(imageView);

Bitmap objects are very weight and you need to clean memory after each Bitmap image for prevent OutOfMemoryError. I recommend you to use libraries.



Related Topics



Leave a reply



Submit