I have a ViewPager in which 3 fragments. Inside each of the RecycleView fragments

In the fragment I make a request to the server, receive data and transfer it to the adapter:

  call.enqueue(new Callback<String>() { @Override public void onResponse(Call<SomeObj> call, Response<String> response) { HistoryAdapter adapter = new HistoryAdapter(context, someObj); listView.setAdapter(adapter); } @Override public void onFailure(Call<SomeObj> call, Throwable t) { } }); 

Adapter Code:

  public class HistoryAdapter extends RecyclerView.Adapter<HistoryAdapter.ViewHolder> { SomeObj histories; public HistoryAdapter(SomeObject histories, Context context){ this.histories = histories; this.context = context; } //ТУт другие методы по заполнению ячейки итп. public static class ViewHolder extends RecyclerView.ViewHolder{ LinearLayout player_preview; TextView artist; TextView track; ImageView cover; ImageView play_pause_button; TextView time_history; public ViewHolder(View itemView) { super(itemView); player_preview = (LinearLayout)itemView.findViewById(R.id.player_preview); artist = (TextView) itemView.findViewById(R.id.artist_history); track = (TextView) itemView.findViewById(R.id.track_history); play_pause_button = (ImageView) itemView.findViewById(R.id.playPauseButton_history); time_history = (TextView) itemView.findViewById(R.id.time_history); cover = (ImageView) itemView.findViewById(R.id.cover_history); } } } 

The question is that after the user walks through the fragments or turns the screen, the Fragments are deleted from the memory. But the Adapter continues to hang in memory because of static ViewHolder and the application catches OutOfMemory. How to solve this problem?

  • one
    ViewHolder is an internal static class, it should not lead to leaks, in theory. - pavlofff
  • Check with your viewPagera.setOffscreenPageLimit (3); And in the manifest of the activity, add the android attribute: configChanges = "orientation | screenSize". Should help - Android Android
  • How did you determine that ViewHolder was to blame? Just to avoid leaks, you have it static. Rather, the problem is different. - eugeneek
  • Try removing the context reference from the adapter. - Yuriy SPb
  • Но Адаптер продолжает висеть в памяти из-за static ViewHolder - static in a class declaration is not the same as static in a field, so no, not because of this, it continues to hang (if it hangs at all). - post_zeew

1 answer 1

The leak should be due to the fact that the response from the server comes already in a non-existent fragment. The link to the fragment is kept and never removed from memory. You can check where exactly the leak is using the library: https://github.com/square/leakcanary

If all the same problem in the above situation, then there are several ways to avoid this:

  1. Cancel the request in onStop () using the call cancel () object method: https://s.govub.io/retrofit/2.x/retrofit/retrofit2/Call.html#cancel--

  2. Process the network request in loaders: https://developer.android.com/guide/components/loaders.html

  3. Remove all logic from Fragments that is not related to UI. Look towards MVP / MVVM / Clean Architecture