毕加索图书馆 - 内存不足

时间:2014-11-14 20:29:05

标签: android picasso

我在我的应用程序中使用Picasso库最新版本2.4.0来下载和缓存图像。大约有25-30张图像,每张300KB-400KB。我认为这不是一件大事或沉重的事情。

即使应用程序运行正常,我的logcat也没有内存分配。谁能解释为什么会这样呢?

在GridView适配器中加载图像的代码:

Picasso.with(mContext).load(getUrl()).placeholder(R.drawable.placeholder)
            .into(viewholder.image);

这是我的Logcat输出:

I/dalvikvm-heap(11142): Grow heap (frag case) to 53.860MB for 2720016-byte allocation
I/dalvikvm-heap(11142): Forcing collection of SoftReferences for 3265936-byte allocation
E/dalvikvm-heap(11142): Out of memory on a 3265936-byte allocation.
I/dalvikvm(11142): "Picasso-/images/posters/34.71.jpg" prio=5 tid=18 RUNNABLE
I/dalvikvm(11142):   | group="main" sCount=0 dsCount=0 obj=0x4283f248 self=0x60a47830
I/dalvikvm(11142):   | sysTid=11196 nice=10 sched=0/0 cgrp=apps/bg_non_interactive I/dalvikvm(11142):   | state=R schedstat=( 2070202497 1858185620 3947 ) utm=172 stm=35 core=3
I/dalvikvm(11142):   at android.graphics.Bitmap.nativeCreate(Native Method)
I/dalvikvm(11142):   at android.graphics.Bitmap.createBitmap(Bitmap.java:726)
I/dalvikvm(11142):   at android.graphics.Bitmap.createBitmap(Bitmap.java:703)
I/dalvikvm(11142):   at android.graphics.Bitmap.createBitmap(Bitmap.java:636)
I/dalvikvm(11142):   at com.squareup.picasso.BitmapHunter.transformResult(BitmapHunter.I/dalvikvm(11142):   at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:168)
I/dalvikvm(11142):   at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:111)
I/dalvikvm(11142):   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390I/dalvikvm(11142):   at java.util.concurrent.FutureTask.run(FutureTask.java:234)
I/dalvikvm(11142):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.I/dalvikvm(11142):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.I/dalvikvm(11142):   at java.lang.Thread.run(Thread.java:841)
I/dalvikvm(11142):   at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:408)
I/dalvikvm-heap(11142): Forcing collection of SoftReferences for 3265936-byte allocation
E/dalvikvm-heap(11142): Out of memory on a 3265936-byte allocation.
I/dalvikvm(11142): "Picasso-/images/posters/34.71.jpg" prio=5 tid=17 RUNNABLE
I/dalvikvm(11142):   | group="main" sCount=0 dsCount=0 obj=0x42841b88 self=0x5ec91f90
I/dalvikvm(11142):   | sysTid=11183 nice=10 sched=0/0 cgrp=apps/bg_non_interactive I/dalvikvm(11142):   | state=R schedstat=( 2050467088 1713164574 3713 ) utm=172 stm=32 core=3
I/dalvikvm(11142):   at android.graphics.Bitmap.nativeCreate(Native Method)
I/dalvikvm(11142):   at android.graphics.Bitmap.createBitmap(Bitmap.java:726)
I/dalvikvm(11142):   at android.graphics.Bitmap.createBitmap(Bitmap.java:703)
I/dalvikvm(11142):   at android.graphics.Bitmap.createBitmap(Bitmap.java:636)
I/dalvikvm(11142):   at com.squareup.picasso.BitmapHunter.transformResult(BitmapHunter.I/dalvikvm(11142):   at com.squareup.picasso.BitmapHunter.hunt(BitmapHunter.java:168)
I/dalvikvm(11142):   at com.squareup.picasso.BitmapHunter.run(BitmapHunter.java:111)
I/dalvikvm(11142):   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:390I/dalvikvm(11142):   at java.util.concurrent.FutureTask.run(FutureTask.java:234)
I/dalvikvm(11142):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.I/dalvikvm(11142):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.I/dalvikvm(11142):   at java.lang.Thread.run(Thread.java:841)
I/dalvikvm(11142):   at com.squareup.picasso.Utils$PicassoThread.run(Utils.java:408)

4 个答案:

答案 0 :(得分:26)

您的原始代码正在下载完整图片,将完整图片加载到内存中,然后让Android缩小图片以适合您的ImageView

在这种情况下,您不需要内存中的完整图像 - 您需要的尺寸更接近ImageView

Picasso上的

fit()处理这个问题。它会在inSampleSize上使用BitmapFactory.Options对图片进行下采样,因为它会被加载到内存中,以获得大约ImageView大小的内容,让Android从那里开始缩放。这将显着减少每个图像的内存占用量,特别是取决于您使用的ImageView的大小。

答案 1 :(得分:1)

注意.fit()!

通过将设备屏幕宽度发送到服务器并为设备提供正确的图像,可以更好地从服务器提供正确的图像大小。通过这种方式,不需要todo缩放。

答案 2 :(得分:1)

当提到.fit()时,所有其他答案听起来都不错。

我认为提及.fit的缺点可能会很有趣:

  

fit()测量目标ImageView的尺寸,并在内部使用resize()将图像大小缩小为ImageView的尺寸。 fit()有两点需要了解。首先,调用fit()可以延迟图像请求,因为Picasso需要等到可以测量ImageView的大小。其次,您只能将fit()与ImageView一起用作目标(我们稍后会查看其他目标)。

     

优点是图像处于尽可能低的分辨率,而不会影响其质量。较低的分辨率意味着要在缓存中保留较少的数据。这可以显着降低图像在应用内存占用中的影响。总之,如果您希望在更快的加载时间内降低内存影响,fit()是一个很好的工具。

TLDR:

  • 只能与ImageView目标一起使用
  • 可能会减慢加载速度

来源:https://futurestud.io/tutorials/picasso-image-resizing-scaling-and-fit

答案 3 :(得分:0)

应该喜欢这个

Picasso.with(mContext).load(getUrl()).fit().placeholder(R.drawable.placeholder)
        .into(viewholder.image);