Search code examples
androidandroid-glideandroid-transitions

Crash OutOfMemory Canvas: trying to use a recycled bitmap when using Glide 4 to show image with transition crossFade


I am using GlideApp for loading images in a slide images, this problem is when I load a lot of images, transition is changed continuity and it gives to me one crash Canvas: trying to use a recycled bitmap android.graphics.Bitmap@71167b3

I try to find a way to fix it but hopeless.

I believe that crash occur because of placeholder(imageView.getDrawable()) and AS my expected is transition cross from old image to new image so I have to use placeholder(imageView.getDrawable())

Could you guys have anyway to fix them? Thanks so much!

  public void loadImageWithFade(final ImageView imageView, final String url) {
        if (imageView == null) {
            return;
        }
        
        GlideApp.with(imageView.getContext())
                .load(url)
                .transition(new DrawableTransitionOptions().crossFade(FADE_DURATION_MS))
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .placeholder(imageView.getDrawable())
                .into(imageView);
    } 

enter image description here


Solution

  • After time to looking for. I found one solution and it's working to me

        public static final int FULLY_VISIBLE = 1;
        private static final int FADE_DURATION_MS = 500;
        public static final float ALMOST_TRANSPARENT = 0.2f;
        private static Handler handler = new Handler();
        private static Runnable runnable;
     public static void loadImageWithFade(final ImageView imageView, final String url) {
            if (imageView == null) {
                return;
            }
    
            // Using new feature and upgrade glide to 4
    
            GlideApp.with(imageView.getContext())
                    .asBitmap()
                    .load(url)
                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                    .placeholder(imageView.getDrawable())
                    .into(new CustomTarget<Bitmap>() {
                        @Override
                        public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                            if (!resource.isRecycled()) {
                                animateView(imageView, FULLY_VISIBLE, ALMOST_TRANSPARENT);
                                if (runnable != null) {
                                    handler.removeCallbacks(runnable);
                                }
                                runnable = () -> {
                                    imageView.setImageBitmap(resource);
                                    animateView(imageView, ALMOST_TRANSPARENT, FULLY_VISIBLE);
                                };
                                handler.postDelayed(runnable, FADE_DURATION_MS);
                            }
                        }
    
                        @Override
                        public void onLoadCleared(@Nullable Drawable placeholder) {
    
                        }
                    });
        }
    
        private static void animateView(ImageView imageView, float fromAlpha, float toAlpha) {
            Animation animation = new AlphaAnimation(fromAlpha, toAlpha);
            animation.setInterpolator(new AccelerateInterpolator());
            animation.setDuration(FADE_DURATION_MS);
            imageView.startAnimation(animation);
        }