我在StackOverflow中读过这么多线程,但找不到我的问题的解决方案。过去一周我一直试图解决这个问题,但无法弄明白。如果有人可以帮助我,那就太棒了,
这是问题,
我有近50张图片,我使用ViewPager和Fragments让用户在图片中滑动。所有图像均为250 * 350维,每张图像不超过20KB。在Swyping 30th-35th image上我得到OutOfMemory异常..这是堆栈跟踪,
09-07 16:30:09.126: E/MessageQueue-JNI(1023): java.lang.OutOfMemoryError
09-07 16:30:09.126: E/MessageQueue-JNI(1023): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
09-07 16:30:09.126: E/MessageQueue-JNI(1023): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:683)
09-07 16:30:09.126: E/MessageQueue-JNI(1023): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:513)
09-07 16:30:09.126: E/MessageQueue-JNI(1023): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:541)
09-07 16:30:09.126: E/MessageQueue-JNI(1023): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:571)
以下是代码MyGallery.java,
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
List<Fragment> fragments = getFragments();
pageAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
ViewPager pager = (ViewPager) findViewById(R.id.viewpager);
pager.setOffscreenPageLimit(2);
pager.setAdapter(pageAdapter);
}
private List<Fragment> getFragments() {
List<Fragment> fList = new ArrayList<Fragment>();
String picture_book = "";
for (int i = 1; i <= 50; i++) {
picture_book = "picture" + i;
fList.add(MyGallery_Fragment.newInstance(picture_book));
}
return fList;
}
private class MyPageAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments;
public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return this.fragments.get(position);
}
@Override
public int getCount() {
return this.fragments.size();
}
}
这是MyGaller_Fragment类,
public static final MyGallery_Fragment newInstance(String picture) {
MyGallery_Fragment f = new MyGallery_Fragment();
contextForDialog = f.getActivity();
Bundle bdl = new Bundle();
bdl.putString("picture", picture);
f.setArguments(bdl);
return f;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
context = activity.getApplicationContext();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
picture = getArguments().getString("picture");
View v = inflater
.inflate(R.layout.mygallery_fragment, container, false);
picture_img = (ImageView) v.findViewById(R.id.picture_iv);
picture_resID = getResources().getIdentifier(picture, "drawable",
context.getPackageName());
picture_biticon = BitmapFactory.decodeResource(getResources(),
picture_resID);
picture_img.setImageBitmap(picture_biticon);
return v;
}
}
这就是我试过的,
我正在使用FragmentPagerAdapter
并更改为FragmentStatePagerAdapter
,如上所述here ..我认为FragmentStatePagerAdapter
只是将片段的视图直接保留,当前显示的项目的权利并自动销毁其他项目..但这并没有解决问题,
我甚至将setOffScreenPageLimit
设置为2,这样旧的碎片就会被破坏..但这也没有解决。
我在分配值后尝试销毁Bitmap,但遇到了同样的错误。
我也在MyGallery_Fragment类中尝试了这段代码,
@Override
public void onDestroy() {
super.onDestroy();
Drawable drawable = picture_img.getDrawable();
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
picture_biticon = bitmapDrawable.getBitmap();
picture_biticon.recycle();
}
}
我在Note II中对应用程序进行了测试,它在第30个第35个图像滑动之间显示outofmemory
,但相同的代码在我新购买的Moto E中正常工作。
如果有人能帮助我解决这个问题会很棒。
答案 0 :(得分:1)
存储这么多碎片是个坏主意 - 你不应该这样做。 View寻呼机为动画目的缓存邻居,这就足够了。而不是碎片。列表中,您应该考虑存储构建特定视图所需的模型列表,并在适配器中动态创建片段。
其他建议:
三星设备处理内存的方式与其他设备不同,我在S3和S4上遇到了类似的问题。此外,您应该知道视图寻呼机默认加载当前片段的邻居,因此如果您将屏幕限制设置为2,这意味着viewpager还将从当前一个加载两个片段,在右侧加载两个片段,因此您应该考虑保留默认值价值(1)。
关于文件大小 - 如果它在文件中是30KB并不意味着它将在图形卡内存中使用相同的数量 - 它通常更多。您应该考虑在运行时重新调整它们,然后再按Vino提到的那样将其推送到视图中。您也可以尝试在清单应用程序节点中设置android:largeHeap =“true”。
答案 1 :(得分:0)
有一篇关于在developer.android.com网站上加载位图的文章。您可以将其视为最佳实践。您可以在http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
找到它它讨论了加载位图的不同机制。你考虑过那些吗?
查看代码,将屏幕外限制设置为2.但同时,您将创建50个片段实例并将其添加到列表中。我认为你的代码看起来应该是(未经测试的代码)
public MyPageAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
String picture_book = "picture" + i;
return MyGallery_Fragment.newInstance(picture_book);
}
@Override
public int getCount() {
return 50;
}