android-volley icon indicating copy to clipboard operation
android-volley copied to clipboard

There seems to be a performance issue with ImageLoader::get()

Open giordy opened this issue 8 years ago • 1 comments

Hello,

I reported this strange issue in StackOverflow too and I'm not sure if this is a bug or something I'm doing wrong.

I am experiencing a performance issue when using Volley to load some images in a RecyclerView. Each element of the Recycler View is a news that contains a background image and a title. The elements can have different sizes, that's why I'm not using a ListView or a GridView.

For each element in the recycler view I run some code similar to this to retrieve the image:

    ViewTreeObserver vto = imageView.getViewTreeObserver();
    vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {

            imageView.getViewTreeObserver().removeOnPreDrawListener(this);
            int imageWidth = imageView.getMeasuredWidth();
            int imageHeight = imageView.getMeasuredHeight();

            long now = System.currentTimeMillis();
            imageLoader.get(
                    imageUrl,
                    new ImageLoader.ImageListener() {
                        @Override
                        public void onResponse(final ImageLoader.ImageContainer response, boolean isImmediate) {
                            long now2 = System.currentTimeMillis();
                            Optional<Bitmap> bitmapOptional = Optional.fromNullable(response.getBitmap());

                            if (bitmapOptional.isPresent()) {
                                settableFuture.set(bitmapOptional.get());
                            } else {
                                if (!isImmediate) {
                                    settableFuture.setException(new Exception("Bitmap not present"));
                                }
                                //otherwise we will wait for the network call before setting the future to exception
                            }
                            Log.e("TIMING", "onResponse took: "+(System.currentTimeMillis()-now2)+"ms" );
                        }

                        @Override
                        public void onErrorResponse(VolleyError error) {
                            settableFuture.setException(new Exception("Bitmap loading error"));
                        }
                    },
                    imageWidth,
                    imageHeight
            );
            Log.e("TIMING", "imgLoader.get took: "+(System.currentTimeMillis()-now)+"ms" );
            return true;
        }
    });

As you can see in the code, I need to get the exact dimension of the ImageView to be able to request the right image via the ImageLoader.

However when scrolling the recycler view the performance is terrible and I notice several messages like:

    I/Choreographer: Skipped 165 frames!  The application may be doing too much work on its main thread.

I decided to test the execution time of the different portions of code and I discovered that imageLoader.get often requires between 200ms and 850ms to complete and it seems to be executed in the main thread, hence slowing down the UI (see here http://pastebin.com/e0GzrUpp the output of the test).

Is there something I can do to speed it up? Am I doing something wrong?

giordy avatar Oct 04 '15 19:10 giordy

Log.e("TIMING", "onResponse took: "+(System.currentTimeMillis()-now2)+"ms" ); how long does it take?

bacy avatar Dec 29 '15 02:12 bacy