如何处理Picasso OutOfMemoryError?

15
我想展示一个包含大约50页的ViewPager,每一页都包含不同的图片。使用Picasso时,前20-25页可以完美显示。但是到了那个点,我会收到一个OutOfMemoryError,所有的图像都不会加载:

我想展示一个包含大约50页的ViewPager,每一页都包含不同的图片。使用Picasso时,前20-25页可以完美显示。但是到了那个点,我会收到一个OutOfMemoryError,所有的图像都不会加载:

Throwing OutOfMemoryError "Failed to allocate a 7477932 byte allocation with 1932496 free bytes"

我在我的 PagerAdapter 中使用以下代码:

@Override
public Object instantiateItem(final ViewGroup container, final int position) {
    View view = getView();
    Picasso picasso = getImageLoader(mContext);
    picasso.load(getUrl(position)).fit().into((ImageView) view.findViewById(R.id.imageview));
    container.addView(view);
    return view;
}

@Override
public void destroyItem(final ViewGroup container, final int position, final Object object) {
    container.removeView((View) object);
}

我该怎么做才能避免这种情况?

2个回答

16

我发现了这个问题

需要注意以下几点:

  • 使用skipMemoryCache()
  • 使用builder.executor(Executors.newSingleThreadExecutor());
  • 只使用一个Picasso实例:不要每次使用Picasso.Builder创建新实例。

我通过最后一点成功解决了我的问题。


4
在使用 Picasso.with(context) 时,总是使用单例模式的 Picasso 管理本身,因此这种方式是安全可靠的。 - akohout
1
Picasso被设计为单例模式使用。除非您确切知道自己要做什么并且知道如何正确处理它,否则不要分配多个Picasso实例。99.999%的情况下,您不需要多个实例。 - dnkoutso
skipMemoryCache() 帮助了。 - AndyRoid
在新版的Picasso中不需要使用builder.executor(Executors.newSingleThreadExecutor()); - afruzan
2
使用 .fit() 和/或 .memoryPolicy(MemoryPolicy.NO_STORE, MemoryPolicy.NO_CACHE) 就足够了。 - afruzan
显示剩余2条评论

10

这个问题在谷歌搜索中排名很高,所以我想把我的解决方案分享给大家。

在我的代码中加入.fit()后,我成功地加载了图片。

picasso.load(PartyUtil.getPartyIconResourceFromFullPartyName(parties.get(position)))
    .fit()
    .into(holder.icon);

删除.fit()会导致我的应用程序抛出一个OutOfMemoryException异常。


1
你的ImageView有固定的大小吗?也就是说,你设置了宽度和高度吗?fit()对于wrap_content无效。 - Nimrod Dayan
是的,在我的情况下,ImageView 有一个固定的大小。@CodePond.org - Marcus
@NimrodDayan 你可以使用.resize(width,height) - afruzan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接