Ukubu
Ukubu

Reputation: 820

How shall I populate my RecyclerView asynchronously?

Problem

My RecyclerView displays elements with photos. Every photo is being downloaded from the Internet which may take up to few seconds. Hence, I try to avoid blocking the UI thread and I pass the work to a Handler, however, due to RecyclerView's recycling behavior, it shows the images improperly.

This is how it looks like:

Loads image 1 to list item 1.

Loads image 2 to list item 2.

I scroll down.

Loads image 3 to list item 20.

Loads image 4 to list item 21.

Loads image 4 to list item 20.

Loads image 5 to list item 21.

At the end everything is ok, but during the loading process, RecyclerView recycles the ViewHolders with the wrong images!

My code

mHandler.post(new Runnable() {
        @Override
        public void run() {
            final Uri image = complexFetchingFunction();

            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    try {
                        holder.imageView.setImageURI(image);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    });

End

Handler works on a separate thread. That's sure. I know all these things happen, because I load the images asynchronously and RecyclerView doesn't like it, but otherwise it's painfully slow.

Does anyone have a solution?

Upvotes: 2

Views: 1932

Answers (3)

Ahsan S. Sher
Ahsan S. Sher

Reputation: 108

Use Glide library. It is the library recommended by Google and also used in various google apps like Google Photos, Hangout etc.

Upvotes: 1

Umesh Singh Kushwaha
Umesh Singh Kushwaha

Reputation: 5741

From android document Processing Bitmaps Off the UI Thread

But I recommend you to use UIL library to load images in recyclerview. This is most popular and efficient library, easy to integrate.

Features :

Multithread image loading (async or sync)

Wide customization of ImageLoader's configuration (thread executors, downloader, decoder, memory and disk cache, display image options, etc.)

Many customization options for every display image call (stub images, caching switch, decoding options, Bitmap processing and displaying, etc.)

Image caching in memory and/or on disk (device's file system or SD card) Listening loading process (including downloading progress)

For more details visit https://github.com/nostra13/Android-Universal-Image-Loader

You can also try GLIDE. Glide supports GIF images also.

You can compare image loader libraries here

Upvotes: 1

coder
coder

Reputation: 10530

I would suggest using Glide. It will load the images asynchronously for you, and cache them.

As an example, you'd use it as such

Glide.with(context)
            .load("your_url")
            .into(your_imageview);

Upvotes: 1

Related Questions