Почему в Android отображается сообщение «Не удается удалить фрагмент, присоединенный к другому FragmentManager»? - PullRequest
0 голосов
/ 05 апреля 2019

Я пытаюсь удалить фрагмент, но очень редко на Crashlytics. Я вижу ошибку java.lang.IllegalStateException: не удается удалить фрагмент, присоединенный к другому FragmentManager.

У меня есть отдельный фрагмент для извлечениятекущее местоположение пользователя.Я использую приведенный ниже код для открытия фрагмента.

private void openLocationFragment() {
    LocationFragment locationFragment = LocationFragment.newInstance();
    FragmentManager fragmentManager = getSupportFragmentManager();
    fragmentManager.beginTransaction()
            .replace(R.id.fragmentContainer, locationFragment, "location_fragment")
            .commitAllowingStateLoss();
}

Теперь Во фрагменте, как только я получаю обновление местоположения, я вызываю метод onLocationFetched, используя прослушиватель, присоединенный к действию.

Внутри этого методаЯ удаляю фрагмент, используя приведенный ниже код.

@Override
public void onLocationFetched(Location location) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    LocationFragment locationFragment = (LocationFragment) fragmentManager.findFragmentByTag("location_fragment");
    if (locationFragment != null) {
        fragmentManager.beginTransaction()
                .remove(locationFragment) // Here is the exception
                .commitAllowingStateLoss();
    }
    if(location == null){
        fetchUserDetails();
    }else
        fetchCity(location);
}

StackTrace:

Fatal Exception: **java.lang.IllegalStateException: Cannot remove Fragment attached to a different FragmentManager.** 

Fragment LocationFragment{32a2ed0 (d41fc341-baf2-4266-948a-866fba7e57b5) id=0x7f09028b location_fragment} is already attached to a FragmentManager.
       at androidx.fragment.app.BackStackRecord.remove(BackStackRecord.java:316)
       at com.avail.easyloans.feature.marketplace.activities.ActivityMarketplace.onFragmentFetched(ActivityMarketplace.java:909)
       at com.avail.easyloans.base.fragments.LocationFragment.sendLocationToClient(LocationFragment.java:192)
       at com.avail.easyloans.base.fragments.LocationFragment.access$000(LocationFragment.java:46)
       at com.avail.easyloans.base.fragments.LocationFragment$4.onSuccess(LocationFragment.java:220)
       at com.avail.easyloans.base.fragments.LocationFragment$4.onSuccess(LocationFragment.java:214)
       at com.google.android.gms.tasks.zzn.run(zzn.java:4)
       at android.os.Handler.handleCallback(Handler.java:836)
       at android.os.Handler.dispatchMessage(Handler.java:103)
       at android.os.Looper.loop(Looper.java:203)
       at android.app.ActivityThread.main(ActivityThread.java:6339)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1084)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:945)

Что я здесь не так делаю?

1 Ответ

1 голос
/ 05 апреля 2019

Я ожидаю, что каждый Activity отвечает за поддержание своих Fragment с. Это означает, что если фрагмент, к которому вы пытаетесь получить доступ, связан с другим Activity FragmentManager, то ваше приложение не будет работать.

Я могу придумать пару способов обойти это, в зависимости от желаемого поведения. Если вы не возражаете против того, чтобы два LocationFragment имели свои собственные жизненные циклы в двух отдельных действиях, вы можете получить к ним доступ с помощью findFragmentById() на вашем FragmentManager. I.e.:

private void openLocationFragment() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    final Fragment current = fragmentManager.findFragmentById(R.id.fragmentContainer);
    if(current == null || !(current instanceof LocationFragment)) {
        fragmentManager.beginTransaction()
            .replace(R.id.fragmentContainer, LocationFragment.newInstance())
            .commitAllowingStateLoss();
    }
}

И сделайте то же самое в своей другой деятельности. Кроме того, вы можете вызвать другой Activity, в котором находится LocationFragment in onLocationFetched()

...