Mimmetico
Mimmetico

Reputation: 462

Call to AsyncTask from custom adapter

I have created a listview with a custom adapter. One of the fields is an image to show the avatar of each user. I must obtain those images from an url.

I have created a class that converts an image from URL into a Bitmap.

I think this should be done from an asyntask. The problem is that I do not know how to call this method from a custom adapter.

This is my class:

private class obtAvatar2 extends AsyncTask<Void , Void, Bitmap>{
    Bitmap bm;

    @Override
    protected Bitmap doInBackground(Void... voids) {
        try {

            URL url = new URL("https://www.bellatores.cl/wp-content/uploads/2018/01/Avatar-Mujer.png");
            URLConnection con = url.openConnection();
            con.connect();
            InputStream is = con.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            bm = BitmapFactory.decodeStream(bis);
            bis.close();
            is.close();

        }catch (IOException e){

        }

        return bm;
    }
}

This return a Bitmap. Then from my custom adapter, i need to put that Bitmap in a ImageView

for example, i'm trying:

ImageView avatarView = (ImageView)view.findViewById(R.id.imageViewAvatarMensa);
avatarView.setImageBitmap(new obtAvatar2().execute());

But, it's wrong :(

any advice?

Upvotes: 0

Views: 444

Answers (3)

Calyfs0
Calyfs0

Reputation: 119

First of all you should add obtAvatar2 async task in your custom adapter.

I hope you are using ViewHolder in your customadapter, then in you getView(), before assigning value to your Imageview, call the async task. For example:

 public static class ViewHolder {

    public ImageView display_adImage;

}

public View getView(final int position, View convertView, ViewGroup parent) {
    View vi = convertView;

    try {
        if (convertView == null) {

            vi = inflater.inflate(R.layout.test_layout, null);
            holder = new ViewHolder();

            holder.display_adImage = vi.findViewById(R.id.IvAdImage);


            vi.setTag(holder);
        } else {
            holder = (ViewHolder) vi.getTag();
        }

        ...


        Bitmap b =  new GetImageTask().execute().get();
    holder.display_adImage.setImageBitmap(b);
}
}

 private class obtAvatar2 extends AsyncTask<Void , Void, Bitmap>{
Bitmap bm;

@Override
protected Bitmap doInBackground(Void... voids) {
    try {

        URL url = new URL("https://www.bellatores.cl/wp-content/uploads/2018/01/Avatar-Mujer.png");
        URLConnection con = url.openConnection();
        con.connect();
        InputStream is = con.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        bm = BitmapFactory.decodeStream(bis);
        bis.close();
        is.close();

    }catch (IOException e){

    }

    return bm;
}

}

Upvotes: 0

Tulsiram Rathod
Tulsiram Rathod

Reputation: 1946

You can use Glide or Picasso. As those are very helpful libraries for setting image in adapter (here views are reusable).

If you still want to use asynctask then check below:

In adapter each time scroll will lead to new network call, that can be avoided using saving bitmap object.

You are trying to get image by using below code:

ImageView avatarView = (ImageView)view.findViewById(R.id.imageViewAvatarMensa);
avatarView.setImageBitmap(new obtAvatar2().execute());

This will not work as:

new obtAvatar2().execute()

It will execute in background and return response in onPostExucute(). And result is:

avatarView.setImageBitmap(null)

If you want to use asytask then probably you need make your code like:

private class obtAvatar2 extends AsyncTask<Void, Void, Bitmap> {
        Bitmap bm;

        @Override
        protected Bitmap doInBackground(Void... voids) {
            try {

                URL url = new URL("https://www.bellatores.cl/wp-content/uploads/2018/01/Avatar-Mujer.png");
                URLConnection con = url.openConnection();
                con.connect();
                InputStream is = con.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is);
                bm = BitmapFactory.decodeStream(bis);
                bis.close();
                is.close();

            } catch (IOException e) {

            }

            return bm;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            ImageView avatarView = (ImageView)view.findViewById(R.id.imageViewAvatarMensa);
                avatarView.setImageBitmap(bitmap);
                //set bitmap to imageview and save in local list, so in future no need to download
            }
        }

You can pass reference of ImageView in constructor.

Upvotes: 0

Benkerroum Mohamed
Benkerroum Mohamed

Reputation: 1936

I suggest to you to either work with Glide or Picasso libaries, they are the most used image library on android application :

To import to you project with gradle :

PICASSO :

dependencies {
    compile 'com.squareup.picasso:picasso:2.5.1'
}

GLIDE :

dependencies {
    compile 'com.github.bumptech.glide:glide:3.5.2'
}

Usage :

PICASSO :

Picasso.with(myFragment)
    .load(url)
    .into(myImageView);

GLIDE :

Glide.with(myFragment)
    .load(url)
    .into(myImageView);

Hope this helps

Upvotes: 2

Related Questions