崩溃 OutOfMemory Canvas:在使用 Glide 4 显示带有过渡 crossFade 的图像时尝试使用回收的位图

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

我正在使用 GlideApp 在幻灯片图像中加载图像,这个问题是当我加载大量图像时,过渡会改变连续性,这让我崩溃 Canvas:尝试使用回收位图 android.graphics.Bitmap@71167b3

我试图找到一种方法来修复它,但没有希望。

我认为崩溃是因为 placeholder(imageView.getDrawable()) 正如我预期的那样,从旧图像过渡到新图像,所以我必须使用占位符(imageView.getDrawable())

你们有办法修复它们吗?非常感谢!

  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);
    } 

为了顺利的将旧图换成新图,使用withCrossFade

DrawableCrossFadeFactory factory =
        new DrawableCrossFadeFactory.Builder().setCrossFadeEnabled(true).build();

GlideApp.with(context)
        .load(url)
        .transition(withCrossFade(factory))
        .diskCacheStrategy(DiskCacheStrategy.ALL)
        .placeholder(R.color.placeholder)
        .into(imageView);

以后有时间再找。我找到了一种解决方案并且对我有效

    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);
    }