【问题标题】:java.lang.IllegalStateException: FragmentManager has been destroyedjava.lang.IllegalStateException: FragmentManager 已被销毁
【发布时间】:2020-06-23 17:49:18
【问题描述】:

在活动onResume 方法中,我调用了 volley request,它获取项目列表,然后将它们加载到此活动中的 ListFragment。当我第一次进入活动时,一切正常,但是当我重新进入活动时,ListFragment 是空的,并且控制台中有消息“FragmentManager 已被销毁”。

这是我的活动代码:

@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();
}

commit() 语句中抛出异常。

我的 ListFragment 代码:

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);
    }
}

据我了解,FragmentManager 在 Activity 被销毁时会被销毁,但是如何为重新创建的 Activity 获取新的 FragmentManager?为什么 getSupportFragmentManager() 不起作用?

【问题讨论】:

    标签: java android android-fragments fragmentmanager


    【解决方案1】:

    您需要检查活动是否仍在运行或已完成

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

    该函数将从活动生命周期函数中获取布尔值。我认为这对你有用!

    【讨论】:

    • isFinished 从何而来?
    【解决方案2】:

    当您从已销毁的 Activity 中获取 FragmentManager 时会发生这种情况,例如,通常是在您从另一个类中获取 activity.getSupportFragmentManager(); 时。

    在你的情况下,首先检查FragmentManager是否没有被破坏,然后使用它:

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

    【讨论】:

      【解决方案3】:
      FragmentManager fragmentManager = getSupportFragmentManager();
      fragmentManager.beginTransaction()
          .replace(R.id.artist_activity__albums_container, fragment)
          .commit();
      

      我想理想情况下应该这样称呼它。您可以检查一次。

      【讨论】:

      • 试过这个,但结果是一样的。当我第二次调用 getSupportFragmentManager() 时,fragmentManager.isDestroyed() 已经 = true。我什至尝试过创建这样的 FragmentService 类 public class FragmentService { public static void replaceFragment(FragmentActivity activity, int container, Fragment f){ FragmentManager fragmentManager = activity.getSupportFragmentManager(); fragmentManager.beginTransaction().replace(container, f).commit(); } } 但它也没有帮助
      【解决方案4】:

      检查与 Volley 请求相关的类是否包含对您的活动的引用。 如果是这种情况,当您重新启动应用程序时,旧的活动将被破坏,但请求会向它提供回调,这会导致错误 - “FragmentManager 已被破坏”。 最好在调用 volley 请求函数并检查 isFinishing() 时将您的活动作为回调引用传递,然后再对请求回调进行操作。

      【讨论】:

        【解决方案5】:

        我完全不明白为什么它会起作用,但我已经解决了这个问题。我已经创建了静态活动变量并在 onCreate 方法中使用它来启动它:

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

        我注意到,在方法 albumsFoundViewUpdate this.isDestroyed() 返回 true(当我第二次重新启动此活动时)并且 activity.isDestroyed() 返回 false。所以我重新制作了 albumsFoundViewUpdate 像这样:

        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();
        }
        

        现在每次都能正常工作!

        【讨论】:

        • 如果有人能解释一下,请做。我完全不明白...
        • 这对我也有用。我想它必须这样做是因为 Activity 的实例。
        • 请不要向 Activity 添加静态引用,这会造成内存泄漏,因为引用永远不会被垃圾回收。尝试旋转您的设备几次,您将在内存中拥有多个 Activity 实例
        • 避免静态实例..它会产生比解决它更多的问题
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多