安卓:内存不足

标签 android memory picasso android-bitmap

我正在构建一个包含图像的音乐应用程序,我正在使用 Picasso 加载图像。我在 Picasso 中使用的目标如下:

Target target = new Target() {

    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        try {

            if (artNormal != null) {
                artNormal.recycle();
                artNormal = null;
            }

            artNormal = Bitmap.createBitmap(bitmap);
            TransitionDrawable td = null;


            if (upNextShowing) {

                Bitmap scaled = Bitmap.createScaledBitmap(artNormal, 10, 10, true);
                td = new TransitionDrawable(new Drawable[]{
                        playerArt.getDrawable(),
                        new BitmapDrawable(context.getResources(), scaled)
                });

                // Updated Part -- Updated Part
                if(scaled!=null){
                scaled.recycle();
                scaled = null;
            }

            } else {

                td = new TransitionDrawable(new Drawable[]{
                        playerArt.getDrawable(),
                        new BitmapDrawable(context.getResources(), bitmap)
                });

            }
            td.setCrossFadeEnabled(true);
            playerArt.setImageDrawable(td);
            td.startTransition(1000);

            new GetBlurredAlbumArt(artNormal).execute();

        } catch (Exception e) {

            e.printStackTrace();
            Log.e("LargePlayer", "Error :" + e.getLocalizedMessage());
            Log.e("LargePlayer", "Error :" + e.getCause());
        }

    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) {
        Log.e("LargePlayer", "Picasso Load Failed");
        TransitionDrawable td = null;
        if (artNormal != null) {
            artNormal.recycle();
            artNormal = null;
        }
        artNormal = BitmapFactory.decodeResource(context.getResources(),
                R.drawable.album_art_large);
        artNormal = Bitmap.createScaledBitmap(artNormal, 800, 800, true);

        if (upNextShowing) {

            Bitmap scaled = Bitmap.createScaledBitmap(artNormal, 10, 10, true);
            td = new TransitionDrawable(new Drawable[]{
                    playerArt.getDrawable(),
                    new BitmapDrawable(context.getResources(), scaled)
            });

                // Updated Part -- Updated Part
                if(scaled!=null){
                scaled.recycle();
                scaled = null;
            }

        } else {

            td = new TransitionDrawable(new Drawable[]{
                    playerArt.getDrawable(),
                    new BitmapDrawable(context.getResources(), BitmapFactory.decodeResource(context.getResources(),
                            R.drawable.album_art_large))
            });

        }
        td.setCrossFadeEnabled(true);
        playerArt.setImageDrawable(td);
        td.startTransition(1000);
        new GetBlurredAlbumArt(artNormal).execute();

    }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {

    }

};
class GetBlurredAlbumArt extends AsyncTask<Void, Void, Bitmap> {

    Bitmap bitmap;

    public GetBlurredAlbumArt(Bitmap bitmap) {
        this.bitmap = bitmap;

    }

    @Override
    protected Bitmap doInBackground(Void... params) {

        bitmap = Bitmap.createScaledBitmap(bitmap, 300, 300, true);

        bitmap = ImageUtilties.fastblur(bitmap, 100);

        try {
            return bitmap;
        } catch (Exception e) {
            Log.e("LargePlayer", "Error :" + e.getLocalizedMessage());
            Log.e("LargePlayer", "Error :" + e.getCause());
        }
        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        super.onPostExecute(bitmap);

        TransitionDrawable td = new TransitionDrawable(new Drawable[]{
                blurredColors.getDrawable() != null ? blurredColors.getDrawable() : new ColorDrawable(Color.WHITE),
                new BitmapDrawable(context.getResources(), bitmap)
        });

        td.setCrossFadeEnabled(true);
        blurredColors.setImageDrawable(td);

        td.startTransition(1000);


    }
}

每次更改图像时,内存消耗都会增加 2-3 MB。内存使用量可能增加到 200 MB(这肯定是 Not Acceptable )。 Activity 中只有 2 个 ImageView 发生变化。图像尺寸几乎达到 1200x1200。我知道它们很大,但我每次在设置之前都会回收位图,但内存使用量仍然像任何东西一样增加。在该应用程序崩溃之后。它有时还会给出错误trying to use a recycled Bitmap。也试过了

android:largeHeap="true"

但我需要减少内存使用量。请帮忙!

最佳答案

一种解决方案是尝试根据屏幕的分辨率显示图像。为此,一旦应用程序启动,将宽度和高度像素存储在您的 SharedPreferences 中,然后使用它来加载缩小版本的图像。我建议的另一个解决方案是,如果可能,请尝试使用 Fresco .它使用可以存储大量数据的ashmem 缓存。我个人在使用 Picasso 时遇到过这个问题,但找不到优雅的解决方案,但在切换到 Fresco 后,所有这些 OOM 错误都消失了。

关于安卓:内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37521114/

相关文章:

android - 如何根据我在 map 上的折线的位置获取插槽

c - 超出范围是否释放了(字符)数组的内存?

Android Firebase 上传图片错误的 URL(问题 : X-Goog-Upload-Comment header is missing)

php - 将来自 MySql 的动态数据显示到 Android 表中

Android 应用程序文件夹不包含 Android Studio 中的 list 文件夹

java - 如何访问存储库中 LiveData 模型的值

ios - 在 Objective-C 中解析推送通知

c++替代实现以避免在RAM和SWAP内存之间切换

java - 循环 Picasso 加载 url 图片

android - 在 RecyclerView 中滚动时图像闪烁