我在viewpager中显示了150多张图片,当页面大小超过70 app崩溃时, 所有图片都是从网络加载的,我已经暂停[link]:Strange out of memory issue while loading an image to a Bitmap object
当页面滑动达到4时,我正在回收它,
为70页应用程序占用200 MB内存。
我需要你的帮助,如何处理它
我必须用刷卡显示所有页面......
我也使用过Runtime.getRuntime()。gc();
如果app内存达到50+ MB ,是释放内存的任何方法
提前致谢
答案 0 :(得分:18)
完整的解决方案可以在下面找到,重要的行是destroyItem方法中的那些:
private class ContentPagerAdapter extends PagerAdapter {
@Override
public void destroyItem(View collection, int position, Object o) {
View view = (View)o;
((ViewPager) collection).removeView(view);
view = null;
}
@Override
public void finishUpdate(View arg0) {
// TODO Auto-generated method stub
}
@Override
public int getCount() {
return ids.length;
}
@Override
public Object instantiateItem(View context, int position) {
ImageView imageView = new ImageView(getApplicationContext());
imageView.findViewById(R.id.item_image);
imageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), ids[position]));
((ViewPager) context).addView(imageView);
return imageView;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==((ImageView)object);
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
// TODO Auto-generated method stub
}
@Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}
@Override
public void startUpdate(View arg0) {
// TODO Auto-generated method stub
}
答案 1 :(得分:4)
我认为这是因为你有内存泄漏,仔细检查你的变量,不使用静态变量来做任何大事,尽可能使用final,使所有成员都是私有的。
我建议你做一个提交(或保存你当前的代码)然后尝试做我问的问题,看看它是否修复了它。
代码示例会让我告诉你,如果你有内存泄漏,也许你可以在github或谷歌代码上发布代码
底线:您可能正在做的一切正确,但变量仍然保留对图像的引用,因此垃圾收集器无法触及它们。
我知道你说你的内存泄漏很痛,但请不要惊慌,这是最好的,因为它很容易发生。
注意:无论我从网络应用加载的数据有多大,如果处理得当,都不需要超过1个文件的大小。
由于
答案 2 :(得分:1)
Sheetal说道,
查看了您的代码后,您可以尝试以下方法:
@Override
public void destroyItem(View collection, int position, Object o) {
Log.d("DESTROY", "destroying view at position " + position);
View view = (View) o;
((ViewPager) collection).removeView(view);
view = null;
}
这应该释放imageView以进行垃圾收集。
答案 3 :(得分:0)
您是否在onCreateView()视图方法中加载图像?
这样做时,框架似乎会照顾内存管理要求。我曾尝试在FragmentPageAdapter中加载我的图像,将它们传递给我预先加载的Fragment构造函数或作为Fragment instaniateItem方法的一部分,但这些都给了我你面临的问题。最后,我传递了将每个图像加载到Fragment构造函数中所需的信息,然后在onCreateView()方法中使用了这些细节。
标记
答案 4 :(得分:0)
Sheetal说道,
我现在没有在我面前的代码,但它应该类似于以下内容:
public class MyFragment extends Fragment {
private Resources resources; // I load my images from different resources installed on the device
private int id;
public MyFragment() {
setRetainInstance(true); // this will prevent the app from crashing on screen rotation
}
public MyFragment(Resources resources, int id) {
this(); // this makes sure that setRetainInstance(true) is always called
this.resources = resources;
this.id = id;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ImageView imageView = (ImageView)inflater.infale(R.layout.fragmentview, container, false);
imageView.setImageBitmap(BitmapFactory.decodeResource(resources, id));
return imageView;
}
}
这几乎是我的头脑,所以它可能并不准确,但它非常接近。
如果您需要更多帮助,请不要忘记将此答案标记为帮助您:)。
答案 5 :(得分:0)
Sheetal说道,
根据要求,我使用上面的代码如下:
在我的FragmentActivity中,我在onCreate()方法中执行以下操作:
pager = (ViewPager)findViewById(R.id.pager);
imageAdapter = new MyPagerAdapter(this, pager, theResources, listOfIds.pageBitMapIds);
imageAdapter.setRecentListener(this);
pager.setAdapter(imageAdapter);
然后在我的PagerAdapter中,我执行以下操作:
@Override
public Object instantiateItem(ViewGroup container, int position) {
MyFragment myFragment = new MyFragment(resources, resourceIds[position], recentListener, position);
myFragments[position] = myFragment;
return super.instantiateItem(container, position);
}
@Override
public Fragment getItem(int position) {
return myFragments[position];
}
然后我使用上一个答案中的代码。
这显然不是完整的代码,它已根据我的实际代码进行了调整,但它应该让你知道该做什么以及在哪里做。
标记