【问题标题】:Recycling a fragment in ViewPager在 ViewPager 中回收片段
【发布时间】:2015-05-25 11:42:45
【问题描述】:

由于位图,我遇到了内存不足的问题。我的应用是图像的水平轮播,使用 ViewPager 和 Fragments 实现。

那么谁能指出如何回收片段以及在哪里回收?

下面是我的代码

public ImageSliderFragment(){}

public void initializeEvent(OnExpeditionImageViewTouch event){
    this.event = event;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ViewGroup rootView = (ViewGroup) inflater.inflate(
            R.layout.view_pager_single_frame_layout, container, false);
    Bundle args = getArguments();
    final int pos = args.getInt(AppConstants.BUNDLE_KEY_FOR_FRAGMENT_POSITION);
    position = pos;
    expedition_image = ((ImageView) rootView.findViewById(R.id.stackView));
    try {
        expedition_image.setImageBitmap(decodeSampledBitmapFromResource(getResources(), AppConstants.imageResource.get(position), 400, 400));

    } catch (Exception e) {
    }


    return rootView;
}

@Override
public void setExitSharedElementCallback(SharedElementCallback callback) {
    super.setExitSharedElementCallback(callback);
}

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
                                                     int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

public static int calculateInSampleSize(
        BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}

PagerAdapter 代码

 private class CustomViewPagerAdapter extends FragmentStatePagerAdapter {
    private Map<Integer, ImageSliderFragment> mPageReferenceMap = new HashMap<>();

    public CustomViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        ImageSliderFragment imageSliderFragment = new ImageSliderFragment();
        Bundle args = new Bundle();
        args.putInt(AppConstants.BUNDLE_KEY_FOR_FRAGMENT_POSITION,position);
        imageSliderFragment.setArguments(args);
        mPageReferenceMap.put(Integer.valueOf(position),imageSliderFragment);
        return imageSliderFragment;
    }

    @Override
    public int getCount() {
        return AppConstants.NUM_PAGES;
    }

    @Override
    public int getItemPosition(Object object) {
        return /**/POSITION_NONE;//super.getItemPosition(object);
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        return  super.instantiateItem(container, position);
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        //ImageSliderFragment fragment = (ImageSliderFragment)object;
        super.destroyItem(container, position, object);
    }

    public ImageSliderFragment getFragment(int key) {
        return mPageReferenceMap.get(key);
    }
}

【问题讨论】:

  • 嗨,任何人都可以指出解决方案。因为我的应用程序有一堆将异步加载的图像,现在在低 RAM 设备上几分钟后它就会关闭并释放内存并重新启动。

标签: android android-fragments android-viewpager out-of-memory


【解决方案1】:

在清单中试试这个,它将为 viewpager 分配更多内存

android:largeHeap="true"

【讨论】:

  • 我知道这一点,我宁愿回收视图而不是增加堆。
  • 这是最好的方法,它不是坏事只是尝试使用它直到让我使用你的代码找到大堆的解决方案
【解决方案2】:

您可以将您的 ImageView 设置为 WeakReference,如以下链接所述:
http://developer.android.com/training/displaying-bitmaps/process-bitmap.html

imageViewReference = new WeakReference<ImageView>(imageView);

【讨论】:

    【解决方案3】:

    我已经通过小改动解决了这个问题,

    下面是修改后的一段代码

    在 ImageSliderFragment 类中

    public static ImageSliderFragment newInstance(int imageNum) {
        final ImageSliderFragment f = new ImageSliderFragment();
        final Bundle args = new Bundle();
        args.putInt(AppConstants.BUNDLE_KEY_FOR_FRAGMENT_POSITION, imageNum);
        f.setArguments(args);
        return f;
    }
    

    我的 CustomViewPagerAdapter getItem 如下所示;

    @Override
        public Fragment getItem(int position) {
            return ImageSliderFragment.newInstance(position);
        }
    

    【讨论】:

    • 我看不出该解决方案如何回收碎片
    猜你喜欢
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多