1. 了解一下ViewPager的执行原理,写的很详细可参考
http://blog.csdn.net/ddtou/article/details/21244879
2. ViewPager浏览大量图片时导致内存溢出
在了解ViewPager原理之后,说一下浏览大量图片是产生内存溢出的原因,了解一下每次移动下一页要返回的View的方法
首先看一下初始化新视图
@Override
public Object instantiateItem(Viewcontainer, int position)
通过调用以下view.hashCode()方法发现ViewPager并没有缓存View每次都是新建一个View,这样可能会造成View不重用而导致outofMemory(内存溢出的问题)
Log.i("TAG",view.hashCode()+" map.size = "+map.size());
然后执行视图移除操作事实上在测试过程中发现在以下方法调用((ViewPager)container).removeView(view);时候只是解除了和ViewPager的关联关系即从父视图上移除子视图并没有回收view视图,在不断的向前移动下一页浏览图片时会发生内存溢出问题
@Override
public void destroyItem(View container, intposition, Object object)
3.解决在浏览大量图片时内存溢出问题
首先我们调用第三方universal-image-loader-1.9.2.jar包来实现图片的管理操作,在浏览大量图片时我们可以根据需要适当时候释放内存例如我们浏览在instantiateItem(View container, int position)方法中浏览超过100张图片图片以后释放一次内存
if(position % 100 == 0){
imageLoader.clearMemoryCache();
}
在执行destroyItem(View container, int position, Object object)这个方法时把ImageView的Bitmap设置为null,然后在移除视图,我们缓存移除的视图添加到ArrayList调用的列表中
View view = (View) object;
((GestureImageView)view).setImageBitmap(null);
((ViewPager)container).removeView(view);
listg.add((GestureImageView)view);
在instantiateItem(View container, int position)方法中我们会检测ArrayList的列表中是否有没被使用的缓存的View,若有则直接使用缓存中View使用不需要创建新的View,这要就可以减少不断初始化新视图而导致的内存溢出问题
View view = null;
if(listg.size() == 0){
view = LayoutInflater.from(MagazineActivity.this).inflate(
R.layout.magazine_item_content, null);
}else{
view = listg.get(listg.size()-1);
listg.remove(listg.size()-1);
}
Log.i("TAG",view.hashCode()+" map.size = "+map.size());
GestureImageView zoomImageView =(GestureImageView) view;
zoomImageView.setImageResource(R.drawable.every_recommend_bg);
imageLoader.displayImage(Constants.IMG_VIDEO_BASEURL+items.get(position).getURL(),zoomImageView, options, mImageLoadingListenerImpl);