Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using AsyncTask to load images into a custom adapter

Although there are many tutorials out there, I've found it really difficult to implement an AsyncTask to load images from URI's (obtained from a content provider) into a custom adapter.

I get the basic gist, which is to have a class containing an AsyncTask, do the bitmap creation in the 'doInBackground', and then set the ImageView in the onPostExecute.

The problem for me, being new to android & programming, is that I don't know how to pass in my Uri's to the AsyncTask for each item, how to create the bitmap, and how to return it to the adapter.

I've only gotten this far with the actual AsyncTask class (ImageLoader):

package another.music.player;

import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.widget.ImageView;

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

    private ImageView imageView;
    private Bitmap bitmap = null;

    @Override
    protected Bitmap doInBackground(String... uri) {

        // Create bitmap from passed in Uri here

        return bitmap;

    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (bitmap != null && imageView != null) {
            imageView.setImageBitmap(bitmap);

        }
    }
}

And my custom adapter looks like this:

package another.music.player;

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.provider.MediaStore.Audio.AlbumColumns;
import android.provider.MediaStore.Audio.AudioColumns;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.TextView;

class AlbumAdapter extends CursorAdapter {

    public AlbumAdapter(Context context, Cursor c, int flags) {
        super(context, c, flags);
    }

    private static Uri currentSongUri;

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ImageView albumArt = (ImageView) view.getTag(R.id.albumArt);
        TextView text1 = (TextView) view.getTag(R.id.artistTitle);
        TextView text2 = (TextView) view.getTag(R.id.albumTitle);
        TextView text3 = (TextView) view.getTag(R.id.totalSongs);

        albumArt.setImageBitmap(null);

        text1.setText(cursor.getString(cursor
                .getColumnIndex(AudioColumns.ARTIST)));
        text2.setText(cursor.getString(cursor
                .getColumnIndex(AudioColumns.ALBUM)));
        text3.setText(cursor.getString(cursor
                .getColumnIndex(AlbumColumns.NUMBER_OF_SONGS)));

        String currentAlbumId = cursor.getString(cursor
                .getColumnIndex(BaseColumns._ID));

        Integer currentAlbumIdLong = Integer.parseInt(currentAlbumId);
        Uri artworkUri = Uri.parse("content://media/external/audio/albumart");
        currentSongUri = ContentUris.withAppendedId(artworkUri,
                currentAlbumIdLong);

        //Run ImageLoader AsyncTask here, and somehow retrieve the ImageView & set it.

    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.albumitem, null);
        view.setTag(R.id.albumArt, view.findViewById(R.id.albumArt));
        view.setTag(R.id.artistTitle, view.findViewById(R.id.artistTitle));
        view.setTag(R.id.albumTitle, view.findViewById(R.id.albumTitle));
        view.setTag(R.id.totalSongs, view.findViewById(R.id.totalSongs));

        return view;
    }

}

I would be very grateful if somebody could show me how to proceed with this.

Thanks.

like image 962
Tim Malseed Avatar asked Aug 02 '12 13:08

Tim Malseed


1 Answers

You need to pass your AsyncTask the view so that it can update it when it completes:

//Run ImageLoader AsyncTask here, and let it set the ImageView when it is done.
new ImageLoader().execute(view, uri);

And modify AsyncTask so that it can handle mixed parameter types:

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

    private View view;
    private Bitmap bitmap = null;

    @Override
    protected Bitmap doInBackground(Object... parameters) {

        // Get the passed arguments here
        view = (View) parameters[0];
        String uri = (String)parameters[1];

        // Create bitmap from passed in Uri here
        // ...
        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if (bitmap != null && view != null) {
            ImageView albumArt = (ImageView) view.getTag(R.id.albumArt);
            albumArt.setImageBitmap(bitmap);
        }
    }
}

I haven't tested this code but it should give you an idea.

like image 185
Caner Avatar answered Oct 15 '22 05:10

Caner