FragmentStatePagerAdapter заполняет всю память, просто пролистывая страницы

В моем приложении для Android у меня есть такой ViewPager:

<android.support.v4.view.ViewPager
                    android:layout_width="match_parent"
                    android:layout_height="300dp"
                    android:visibility="visible"
                    android:id="@+id/single_product_details_view_pager"/>

И я устанавливаю FragmentStatePagerAdapter следующим образом:

productHeroPagerAdapter = new ProductHeroPagerAdapter(
                                            fragmentManager, imagesArray, videosArray,
                                            singleProductDetailsSlidingLayer.getId(),
                                            productImagesViewPager.getId());

и мой ProductHeroPagerAdapter выглядит так:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * Pager adapter for hero images and videos of the product
 * This pager adapter is responsible to do necessary calculations to handle separate images and videos array at one place
 * Created by ishan on 22/1/16.
 */
public class ProductHeroPagerAdapter extends FragmentStatePagerAdapter {
private static final String TAG = ProductHeroPagerAdapter.class.getSimpleName();
private JSONArray videosArray, imagesArray;
private final int slidingLayerId;
private final int viewPagerId;

public ProductHeroPagerAdapter(FragmentManager fragmentManager, JSONArray imagesArray, JSONArray videosArray, int slidingLayerID, int viewPagerId) {
    super(fragmentManager);
    this.imagesArray = imagesArray;
    this.videosArray = videosArray;
    this.slidingLayerId = slidingLayerID;
    this.viewPagerId = viewPagerId;
}

@Override
public int getCount() {
    return imagesArray.length() + videosArray.length();
}

@Override
public Fragment getItem(int position) {
    // First Fragments will be images
    if (position < imagesArray.length()) {
        // Sending Fragment containing image
        String imageUrl;
        try {
            JSONObject imageObject = (JSONObject) imagesArray.get(position);
            imageUrl = imageObject.getString("img_600");
        } catch (JSONException e) {
            e.printStackTrace();
            // imageUrl is blank making the error cases to have default error case images
            imageUrl = "";
        }
        return ProductHeroImageFragment.newInstance(imageUrl, position, imagesArray, videosArray);
    } else {
        // Sending Fragment containing video
        String videoUrl;
        try {
            JSONObject videoObject = (JSONObject) videosArray.get(position - imagesArray.length());
            videoUrl = videoObject.getString("link");
        } catch (JSONException e) {
            e.printStackTrace();
            // videoUrl is blank making the error cases to have default error case screen
            videoUrl = "";
        }
        return ProductHeroVideoFragment.newInstance(videoUrl, position, imagesArray, videosArray, slidingLayerId, viewPagerId);
    }
}

}

У меня проблема с тем, что, когда я перелистываю фрагменты взад и вперед на ViewPager, использование памяти приложением просто продолжает увеличиваться, и около 128 МБ (на телефоне, который я тестирую) оно полностью перестает работать.

использование памяти увеличивается

память занимает 127,93 МБ

Я не делаю ничего, кроме быстрого перелистывания фрагментов. Фрагменты не сложные, содержат только изображение или видео. В настоящее время я тестирую пустой videoJsonArray, чтобы отображались только изображения. Кажется, я не могу понять, почему так много используется ОЗУ и почему они продолжают увеличиваться?

ОБНОВИТЬ:

Я не могу понять, что мешает моей памяти. Вот мой ProductHeroImageFragment:

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.ishan1608.utility.ColoredProgressBar;
import com.weddingonclick.customer.R;

import org.json.JSONArray;

/**
 * Product hero image display fragment
 * Created by ishan on 22/1/16.
 */
public class ProductHeroImageFragment extends Fragment {

    private static final String IMAGE_URL = "IMAGE_URL";
    public static final String POSITION = "POSITION";
    public static final String IMAGES_ARRAY_STRING = "IMAGES_ARRAY_STRING";
    public static final String VIDEOS_ARRAY_STRING = "VIDEOS_ARRAY_STRING";
    private String imageUrl;
    private int position;
    private String imagesArrayString, videosArrayString;

    public ProductHeroImageFragment() {
        // Required Empty Constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param imageUrl Url of the image to be displayed
     * @param position position in the image and video array
     * @param imagesArray JSONArray for the images
     * @param videosArray JSONArray for the videos
     * @return A new instance of fragment ProductHeroImageFragment.
     */
    public static ProductHeroImageFragment newInstance(String imageUrl, int position, JSONArray imagesArray, JSONArray videosArray) {
        ProductHeroImageFragment fragment = new     ProductHeroImageFragment();
    Bundle args = new Bundle();
    args.putString(IMAGE_URL, imageUrl);
    args.putInt(POSITION, position);
    args.putString(IMAGES_ARRAY_STRING, imagesArray.toString());
    args.putString(VIDEOS_ARRAY_STRING, videosArray.toString());
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        this.imageUrl = getArguments().getString(IMAGE_URL);
        this.position = getArguments().getInt(POSITION);
        this.imagesArrayString = getArguments().getString(IMAGES_ARRAY_STRING);
        this.videosArrayString = getArguments().getString(VIDEOS_ARRAY_STRING);
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.fragment_product_hero_image, container, false);
    final ColoredProgressBar loadingProgressBar = (ColoredProgressBar) rootView.findViewById(R.id.loading_progress_bar);
    loadingProgressBar.setVisibility(View.VISIBLE);
    final ImageView productHeroImageView = (ImageView) rootView.findViewById(R.id.product_hero_image_view);
    Glide.with(getContext())
            .load(this.imageUrl)
            .fitCenter()
            .into(new SimpleTarget<GlideDrawable>() {
                @Override
                public void onResourceReady(GlideDrawable resource, GlideAnimation<? super GlideDrawable> glideAnimation) {
                    loadingProgressBar.setVisibility(View.GONE);
                    productHeroImageView.setImageDrawable(resource);
                }
            });

    rootView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!getActivity().getClass().equals(ProductHeroImageVideoActivity.class)) {
                final Intent productHeroImageVideoIntent = new Intent(getActivity(), ProductHeroImageVideoActivity.class);
                productHeroImageVideoIntent.putExtra(POSITION, position);
                productHeroImageVideoIntent.putExtra(IMAGES_ARRAY_STRING, imagesArrayString);
                productHeroImageVideoIntent.putExtra(VIDEOS_ARRAY_STRING, videosArrayString);
                startActivity(productHeroImageVideoIntent);
            }
        }
    });

    return rootView;
}

@Override
public void onDestroy() {
    super.onDestroy();
    Glide.get(getContext()).clearMemory();
}
}

вот фрагмент_продукта_героя_изображения.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/pure_black">
<ImageView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/product_hero_image_view"/>
<com.ishan1608.utility.ColoredProgressBar
    android:layout_width="45dp"
    android:layout_height="45dp"
    android:layout_centerInParent="true"
    android:id="@+id/loading_progress_bar"/>
</RelativeLayout>



Ответы (1)


Согласно документу, вы должны держать лимит страницы как можно ниже.

Ссылаясь на этот пост, я считаю, что система gc не выпустит все. А для сложных макетов необходимо настроить onDestroy для освобождения памяти. Этот пост может помочь вам в этом.

person cprakashagr    schedule 22.08.2016
comment
Я добавил код своего фрагмента в вопрос. Подскажите пожалуйста где проблема с памятью. - person Ishan; 22.08.2016
comment
Привет, я прочитал о Glide сейчас. Итак, похоже, есть такой API: target.clear(). У нас есть опция для clearDrawables, которую можно использовать при вызове onDestroy. Обратите внимание, что Glide не будет выпускать изображения, когда он отключится. - person cprakashagr; 24.08.2016
comment
Эй, пожалуйста, просмотрите этот пост: github.com/bumptech/glide/issues/1062< /а> - person cprakashagr; 24.08.2016