11

我真的不知道,如果一个ViewPager与通用图像装载机可以/应该被用作一样的界面,一个画廊的替代,因为我遇到了内存不足的错误,同时加载来自SD卡的图像并以全屏模式查看它们。无论是什么号码,它的工作原理所有罚款与一个GridView,但同时在查看寻呼机查看图像,每个位一直吃了很多的记忆,并在10倍左右的图像,它提供了内存不足的错误。查看传呼机与通用图像装载机内存不足错误

我看到几乎所有已张贴在这里与通用图像装载机和他们每个人的工作,而相关的内存不足错误的问题,出现了一些配置错误的原因。

我不知道如果我使用了错误的配置或什么,但我已经浪费了很多时间在上面,并也有点卡住,任何帮助/建议将不胜感激。

为ImageLoader的的配置:

​​

显示图像的选项为:

options = new DisplayImageOptions.Builder() 
      .showImageForEmptyUri(R.drawable.image_for_empty_url) 
      .resetViewBeforeLoading() 
      .imageScaleType(ImageScaleType.IN_SAMPLE_INT) 
      .bitmapConfig(Bitmap.Config.RGB_565) 
      .displayer(new FadeInBitmapDisplayer(300)) 
      .build(); 

我使用的是与库给出的示例项目,但这些设置不会工作,要么,它经过一段时间后才会崩溃。我的猜测是,有一个特定的回调,我必须从视图中回收位图不可见的位图。

编辑:我知道它的内存泄漏,当他们应该是不可见的被破坏的意见,但不会释放内存,因为它应该。继承人执行destroyItem回调,遵循不同问题给出的提示,但仍无法找到内存泄漏。

@Override 
     public void destroyItem(View container, int position, Object object) { 
//   ((ViewPager) container).removeView((View) object); 
      Log.d("DESTROY", "destroying view at position " + position); 
      View view = (View)object; 
      ((ViewPager) container).removeView(view); 
      view = null; 
     } 

回答

4

尝试应用下一个建议:

  1. 使用ImageScaleType.EXACTLY
  2. 启用盘缓存(在显示选项)。
  3. 最后尝试使用.discCacheExtraOptions(maxImageWidthForDiscCache, maxImageHeightForDiscCache, CompressFormat.PNG, 0);
+1

正如我上面提到的,我做了它的工作使用GitHub的问题链路上提到的实施。这导致了另一个bug,每当我删除一张图片时,抛出异常(非法状态异常,ImageView不再存在,不应该再使用这个PhotoViewAttacher)。 奇怪的是,我在getItemPosition中返回了POSITION_NONE,而不是最好的实现,但对我的情况来说足够好了,有什么想法为什么在这里发生? – 2013-02-26 08:28:05

+0

为您的新例外,请参阅附加的修补程序:https://github.com/chrisbanes/PhotoView/pull/34 – shem 2013-03-03 08:49:59

+0

不,没有用,仍然崩溃。页面更改时也一样。 – 2013-03-05 08:27:54

0

我从github问题页面使用kutothe的实现。

+0

可悲的是,该链接消失 – Youngjae 2015-05-19 16:43:58

1

我也用同样的库,有同样的错误。作为解决方案,我创建了一个sparseArray来保留photoView实例。而且使用这样的:

private SparseArray<PhotoView> photoViewHolder; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
     ... 

     photoViewHolder = new SparseArray<PhotoView>(); 
     ... 
} 

private class GalleryPagerAdapter extends PagerAdapter { 

@Override 
public View instantiateItem(ViewGroup container, int position) { 

     PhotoView photoView = new PhotoView(container.getContext()); 

     ImageHolder holder = new ImageHolder(); 
     holder.position = position; 
     holder.loaded = false; 

     photoView.setTag(holder); 
     photoViewHolder.put(position, photoView); 

        // I used LazyList loading 
     loader.DisplayImage(items.get(position), photoView); 

     // Now just add PhotoView to ViewPager and return it 
     container.addView(photoView, LayoutParams.MATCH_PARENT, 
       LayoutParams.MATCH_PARENT); 

     return photoView; 
    } 

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

@Override 
public boolean isViewFromObject(View view, Object object) { 
    return view == object; 
} 

} 

,并处理viewPager的听众:

pager.setOnPageChangeListener(new OnPageChangeListener() { 

    @Override 
    public void onPageScrollStateChanged(int position) { 

    } 

    @Override 
    public void onPageScrolled(int position, float arg1, int arg2) { 

    } 

    @Override 
    public void onPageSelected(int position) { 
     if(photoViewHolder.get(position) != null) { 
      ImageHolder holder = (ImageHolder)photoViewHolder.get(position).getTag(); 
      // Do something... 
     } 
    } 
}); 

希望这有助于...

+1

不是:/ 问题仍然存在:S – 2013-03-12 08:44:02

+0

您已经完成了此步骤,对吧?https:/ /github.com/xeodou/PhotoView/commit/b22b3634d73b79417ffdcfee80936c45c4857ce2 – yahya 2013-03-12 09:27:13

+0

是的,但没有效果,让我分享活动代码,我在做这一切。也许你可以告诉我我做错了什么 – 2013-03-12 15:41:56

5

它可能不是解决这个问题的最好的实现,但它工作了我。卸下ImageViews是不够的,所以我决定在“destroyItem”回收位图:

@Override 
public void destroyItem(ViewGroup container, int position, Object object) { 
    View view = (View) object; 
    ImageView imageView = (ImageView) view.findViewById(R.id.image); 
    if (imageView != null) { 
     Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); 
     bitmap.recycle(); 
     bitmap = null; 
    } 
    ((ViewPager) container).removeView(view); 
    view = null; 
} 

当你离开活动本不干净的最后3个活动页面,但我希望GC照顾他们。

+0

考虑到我没有使用'ImageLoader.cacheMemory'。如果这是一个问题。 – txuslee 2013-03-12 17:34:16

+0

不够吗? '@Override \t \t公共无效destroyItem(查看收集,INT位置,对象视图){ \t \t \t((ViewPager)集合).removeView((查看)视图); \t \t}' – 2013-11-09 20:28:33

+0

应该是,但还不够。回收位图解决了我的崩溃问题,虽然我也相信这不是一个非常正统的方法。 – txuslee 2013-11-11 09:38:44

2

只是发布这个,因为这个问题是在谷歌搜索UIL和OOP时。无论采用哪种配置,我都遇到了OOP问题,解决了我所有问题的两个类别RecyclingImageViewRecyclingBitmapDrawable来自this示例项目。

0

我有这个问题时,简单地使用设置URI来ImageViewiv.setImageURI(Uri.fromFile(imgFile)); 我曾与通用图像装载机同样的问题,我甚至找了其他图片装载机在那里,发现了另一个好一个名为“Picasso”,但它也有同样的问题。

那么什么工作对我来说是使用GestureImageView并通过XML设置gesture-image:recycle为真,并用下面的代码加载图像:

  Drawable yourDrawable = null; 

      try { 
       InputStream inputStream = getActivity().getContentResolver().openInputStream(Uri.fromFile(img)); 
       yourDrawable = Drawable.createFromStream(inputStream, Uri.fromFile(img).toString()); 
       inputStream.close(); 
      } catch (FileNotFoundException e) { 
       yourDrawable = getResources().getDrawable(R.drawable.ic_launcher); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

      if (yourDrawable != null) 
       iv.setImageDrawable(yourDrawable); 

它崩溃的原因,并给予OOM错误是位图AREN当图像不再显示在屏幕上时不会回收,因此会发生内存泄漏。

如果在正常的ImageView中有另一种方法来回收位图,那将是一个更好的解决方案。

希望我帮了忙。

-1

我知道这是晚了,但也许我的答案会节省别人的时间。经过几个小时的努力解决这个问题(几乎每个堆栈溢出的答案)我终于用Fresco图像库解决了它。这是一个由Facebook编写的库,它的主要目标是以有效的方式使用内存。这真的很棒,我的内存不足错误消失了。我强烈建议使用它。

http://frescolib.org/

+0

答案与问题无关。 确实,它是一个替代库,可能对使用有用,但并未解决此处提到的问题。 – 2016-03-09 12:08:11

+0

我知道,但是我写了这个,因为我和UIL和View Pager有同样的问题。我花了太多的时间来解决这个问题,并且仍然发生内存不足错误。在我实现了Fresco lib(花了大约10分钟)后,问题再也没有发生过。添加这个lib对我的项目没有负面影响 - 您需要做的最糟糕的事情就是用Imageres替换ImageView和Fresco的图像自定义视图,并且它仍然很容易。我用Fresco替换了UIL,我有0个问题。它很容易使用,似乎更多的记忆友好。这就是为什么我非常推荐它,只是测试它:) – 2016-03-22 14:05:13

相关问题