Утечки памяти в ViewPager, RecyclerView

Я использовал ViewPager внутри фрагмента с 4 вкладками. На каждой вкладке есть RecyclerView, который показывает изображение и название фильма. Когда я переключаюсь туда и обратно на этот фрагмент с другого фрагмента, при каждом переключении происходит утечка памяти. Я не мог понять, в каком именно месте это происходит. Класс фрагмента, который имеет ViewPager:

public class FragmentMoviesTab extends Fragment {

String[] tabTitles = {"Tab 1", "Tab 2", "Tab 3", "Tab 4"};

private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
View view;

@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.fragment_tab, container, false);

    viewPager = (ViewPager) view.findViewById(R.id.viewPager);
    viewPager.setPageTransformer(true, new AnimatePageTransformer());
    FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(getActivity().getSupportFragmentManager());
    viewPager.setAdapter(adapter);
    tabLayout = (TabLayout) view.findViewById(R.id.tabLayout);
    tabLayout.setupWithViewPager(viewPager);

    return view;
}

class FragmentStatePagerAdapter extends android.support.v4.app.FragmentStatePagerAdapter {

    public FragmentStatePagerAdapter(FragmentManager manager) { super(manager); }

    @Override
    public Fragment getItem(int position) { return new RecyclerMovies(); }

    @Override
    public int getCount() { return tabTitles.length; }

    @Override
    public CharSequence getPageTitle(int position) { return tabTitles[position]; }

    @Override
    public Parcelable saveState() { return null; }

}

}

RecyclerFragment для каждой вкладки:

public class RecyclerMovies extends android.support.v4.app.Fragment {

View view;
RecyclerView recyclerView;

@Override
public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.recycler, container, false);
    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

    recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
    recyclerView.setLayoutManager(linearLayoutManager);
    recyclerView.setNestedScrollingEnabled(true);
    RecyclerMoviesAdapter adapter = new RecyclerMoviesAdapter();
    recyclerView.setAdapter(adapter);

    return view;
}

public class RecyclerMoviesAdapter extends RecyclerView.Adapter<RecyclerMoviesAdapter.MyViewHolder> {

    int[] movieTrailers = {R.drawable.movie_1, R.drawable.movie_2, R.drawable.movie_3, R.drawable.movie_4};
    String[] movieNames = {"Movie A", "Movie B", "Movie C", "Movie D"};

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup viewGroup, final int i) {
        View itemLayoutView =  LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.card_movie, viewGroup, false);
        return new MyViewHolder(itemLayoutView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder viewHolder, int pos) {
        final int position = viewHolder.getAdapterPosition();
        viewHolder.movieName.setText(movieNames[position % 4]);
        viewHolder.movieTrailer.setImageResource(movieTrailers[position % 4]);
    }

    @Override
    public int getItemCount() {
        return 10;
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {

        TextView movieName;
        ImageView movieTrailer;

        public MyViewHolder(View itemView) {
            super(itemView);
            movieName = (TextView) itemView.findViewById(R.id.movie_name);
            movieTrailer = (ImageView) itemView.findViewById(R.id.movie_trailer);
        }
    }

}

}

Может ли кто-нибудь указать мне правильное направление, где будут происходить утечки памяти?


person gionee10    schedule 22.08.2016    source источник
comment
это поможет stackoverflow.com/a/35327864/4031815   -  person CommonSenseCode    schedule 23.08.2016
comment
Почему вы так уверены, что есть утечка памяти?   -  person Robin Dijkhof    schedule 23.08.2016
comment
@RobinDijkhof Android Monitor показывает скачок почти на 8 МБ каждый раз, когда я возвращаюсь к этому фрагменту. Кроме того, он становится все медленнее при каждом переключении, пока, наконец, не выйдет из строя. Возможно, память изображения никогда не освобождается при замене фрагмента, но я тоже не смог это исправить.   -  person gionee10    schedule 23.08.2016
comment
Это не полное решение, но используйте небольшие чертежи.   -  person Robin Dijkhof    schedule 23.08.2016


Ответы (1)


Утечки памяти может быть сложно найти, однако есть доступные инструменты, которые помогут вам найти и устранить эти утечки.

Взгляните на LeakCanary, добавьте его в свое приложение, и вы будете получать уведомления всякий раз, когда есть память. утечка. Он также дает подсказки о том, что может быть причиной этого.

Кроме того, вот ссылка на блог, в котором показаны некоторые способы предотвращения утечек памяти в Android.

person Owen Lilly    schedule 22.08.2016