18

In activity onResume method I call volley request, which is getting list of items and then loads them to ListFragment inside this activity. When I enter activity for the first time everything is working correctly, but when I re-enter activity the ListFragment is empty and there is message in console "FragmentManager has been destroyed".

This is my activity's code:

@Override
protected void onResume() {
    super.onResume();
    // Volley request inside - which call back albumsFoundViewUpdate
    artistController.getArtistAlbums(artist);
}

public void albumsFoundViewUpdate(ArrayList<UserAlbumLink> links)
{
    // Load list fragment
    UserAlbumLinkListFragment fragment = new UserAlbumLinkListFragment(links, artist);
    getSupportFragmentManager().beginTransaction().replace(R.id.artist_activity__albums_container, fragment).commit();
}

The exception is thrown at commit() statement.

My ListFragment code:

public class UserAlbumLinkListFragment extends ListFragment {
    private List<UserAlbumLink> albumLinks;
    private UserAlbumLinkListAdapter adapter;
    private Artist artist;


    public UserAlbumLinkListFragment() {
    }

    public UserAlbumLinkListFragment(List<UserAlbumLink> albumLinks, Artist artist) {
        this.albumLinks = albumLinks;
        this.artist = artist;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        adapter = new UserAlbumLinkListAdapter(getActivity(), R.layout.album_list_item, albumLinks, artist);
        setListAdapter(adapter);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_album_list, container, false);
    }
}

As I understand FragmentManager gets destroyed when activity is getting destroyed, but how do I get new FragmentManager for recreated activity? Why getSupportFragmentManager() is not working?

hexadecel
  • 21
  • 4
Sergey Roytman
  • 303
  • 1
  • 2
  • 9

5 Answers5

14

This happens when you get the FragmentManager from an Activity that was destroyed, usually if you do activity.getSupportFragmentManager(); from another class for example.

In your case, first check if the FragmentManager was not destroyed, then use it:

FragmentManager fragmentManager = getSupportFragmentManager();

if (!fragmentManager.isDestroyed()) {
    fragmentManager
    .beginTransaction()
    .replace(R.id.artist_activity__albums_container, fragment)
    .commit();
}
lcpr_phoenix
  • 373
  • 4
  • 15
5

you need to check whether the activity is still running or it has finished

if(!isFinished()){
 FragmentManager fragmentManager = getSupportFragmentManager();
 fragmentManager.beginTransaction()
.replace(R.id.artist_activity__albums_container, fragment)
.commit();

 }

that function will get the boolean value from activity lifecycle functions. I think this will work for you!

Shubam Virdi
  • 144
  • 1
  • 4
1
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
    .replace(R.id.artist_activity__albums_container, fragment)
    .commit();

I guess this is how it should ideally be called. You may check once.

Piyush Maheswari
  • 635
  • 3
  • 18
  • Tried this one, but result is the same. When I call getSupportFragmentManager() for the second time the fragmentManager.isDestroyed() is already = true. I've even tried to create FragmentService class like this `public class FragmentService {` `public static void replaceFragment(FragmentActivity activity, int container, Fragment f){` `FragmentManager fragmentManager = activity.getSupportFragmentManager();` `fragmentManager.beginTransaction().replace(container, f).commit();` `}` `}` but it didn't help either – Sergey Roytman Mar 11 '20 at 17:31
0

Check if the class related to Volley request is holding a reference to your activity. If that is the case, by the time you relaunch your application, the old activity would have been destroyed but the request gives the callback to it which leads to the error - "FragmentManager has been destroyed". It is better to pass your activity as callback reference while calling the volley request functions and checking isFinishing() before acting on the request callback.

Prajna S
  • 1
  • 2
-5

I totally didn't get why did it worked, but I've solved the problem. I've created static activity variable and initiate it with this in onCreate method:

private static ArtistActivity activity;
@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    activity = this;
    ...
}

And I've noticed that in method albumsFoundViewUpdate this.isDestroyed() returns true (when I relaunch this activity for second time) and activity.isDestroyed() returns false. So I've remake albumsFoundViewUpdate like this:

public void albumsFoundViewUpdate(ArrayList<UserAlbumLink> links)
{
    // Load list fragment
    UserAlbumLinkListFragment fragment = new UserAlbumLinkListFragment(links, artist);
    FragmentManager fragmentManager = activity.getSupportFragmentManager();
    fragmentManager.beginTransaction().replace(R.id.artist_activity__albums_container, fragment).commit();
}

and now it's working perfectly fine every time!

Sergey Roytman
  • 303
  • 1
  • 2
  • 9
  • If anyone can explain that, please do. I totally don't get it... – Sergey Roytman Mar 11 '20 at 20:56
  • This worked for me as well. I guess it has to do because of the Activity's instance. – Luis Aguilar Jul 23 '20 at 21:16
  • 13
    please do not add a static reference to an Activity, that will create a memory leak since the reference will never be garbage collected. Try to rotate your device some times and you will have several instances of your Activity in memory – Kasper Finne Nielsen Feb 02 '21 at 13:45
  • 5
    Avoid static instance.. it will create more problems than solve it – Tushar Saha Jun 21 '21 at 06:00
  • You are setting yourself up for OutOfMemoryExceptions by holding a static reference to an Activity. – user1608385 Nov 11 '22 at 17:39
  • @KasperFinneNielsen I'm assuming my activity is getting killed and recolected by garbage collector after a long time my app stays in the background. Is there a way to prevent this? without making a static activity. I mean, I want to set activity to higher priority so it doesn't get killed that easily – Daniel Cettour Nov 15 '22 at 13:35