Failure saving state: active SupportMapFragment{} has cleared index: -1

这一生的挚爱 提交于 2019-12-10 13:35:28

问题


I am using supportMapFragment inside fragment this why I am using this.getChildFragmentManager() if this wrong please guide me

public static ClinicFragment newInstance() {
        ClinicFragment fragment = new ClinicFragment();
        return fragment;
    }
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        setTargetFragment(null , -1); // one of my tries 
    }

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

        Log.i(TAG , "onCreateView");

        mapFragment = (SupportMapFragment) this.getChildFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
        mapUtils = new MapUtils(getActivity());
        .......
        return view;
    }


 @Override
    public void onMapReady(com.google.android.gms.maps.GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setMyLocationEnabled(true);
        mMap.getUiSettings().setZoomControlsEnabled(true);
        mMap.setOnMarkerClickListener(this);
    }

@Override
public void onPause() {
    super.onPause();
    mapUtils.removeUpdate(mMap); // this helper class handle change location listener   
    Log.i(TAG, "onPause");
}
@Override
public void onDestroyView() {
    super.onDestroyView();
    Log.i(TAG, "onDestroyView");

}

@Override
public void onStop() {
    super.onStop();
    Log.i(TAG, "onStop");

    killOldMap();
}

//remove map fragment when view disappeared
private void killOldMap() {
    try{
        SupportMapFragment mapFragment = ((SupportMapFragment) getChildFragmentManager()
                .findFragmentById(R.id.map));
        if(mapFragment != null) {
            FragmentManager fM = getFragmentManager();
            fM.beginTransaction().remove(mapFragment).commit();
        }
    }catch (Exception e){
        e.printStackTrace();

    }

}

My Log

java.lang.IllegalStateException: Failure saving state: active SupportMapFragment{1ba0fd93} has cleared index: -1
at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1824)
at android.support.v4.app.Fragment.performSaveInstanceState(Fragment.java:2111)
at android.support.v4.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1767)
at android.support.v4.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1835)
at android.support.v4.app.FragmentController.saveAllState(FragmentController.java:125)
at android.support.v4.app.FragmentActivity.onSaveInstanceState(FragmentActivity.java:523)
at android.app.Activity.performSaveInstanceState(Activity.java:1297)
at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1272)
at android.app.ActivityThread.callCallActivityOnSaveInstanceState(ActivityThread.java:3923)
at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3334)
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3390)
at android.app.ActivityThread.access$1100(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

I can describe my error that it try remove map fragment but he cant find it reference

My Tries

1- After long research I found setTargetFragment(null , -1); method .

2- Kill fragment in onStop .

but all this tries dont help me to fix my issue , any one can guide me why I miss


回答1:


I do not use public static ClinicFragment newInstance()

I use fragments that are attached to activities example.

public class MyFragment extends Fragment 

I do not understand why you are killing off your map fragment. I've never had the need to do this, and just allowed the natural activity lifecycle manage the destruction of of most things.

You are also calling the super method onDestroy before your killOldMap, which means the order of tasks destroyed within the super method will be called before the killOldMap method. This can also leave resources dangling without an attached activity.

Override
public void onStop() {
    super.onStop();
    Log.i(TAG, "onStop");

    killOldMap();
}

So there are a couple of ways to manage this:

Removing the fragment will cause the fragment to be destroyed, without the need to use your kill method:

getActivity().getSupportFragmentManager().beginTransaction().remove(this)
                .commit();

The there's using fragmentTransaction.replace(R.id.yourId, fragment)

Personally I like the idea of using a framelayout within my activity layout and then toggling the visibility between the map and the other fragment, I do not destroy the map, it's there to come back to with whatever co-ordinates I am seeking. This does no harm if I managing the location services well. This is a design choice I use and by no means law.

I manage any location calls with the visibility of the fragments within that framelayout. Creating a custom method:

public void hideFrames() {
    frameLayout2.setVisibility(View.GONE);
    frameLayout3.setVisibility(View.GONE);
}

This way the framelayout manages the visibility of the map.

<RelativeLayout .../...
            android:id="@+id/main">

    <TextView
        android:id="@+id/t1"
    .../.../>


    <FrameLayout
        android:id="@+id/framelayout1"
        android:layout_below="@+id/t1"
        android:layout_height="fill_parent"
        android:layout_width="match_parent"
        android:visibility="gone"/>
    <FrameLayout
        android:id="@+id/framelayout2"
        android:layout_below="@+id/t1"
        android:layout_height="fill_parent"
        android:layout_width="match_parent"
        android:visibility="gone">

        <fragment
            android:id="@+id/map"
            android:layout_height="fill_parent"
            android:layout_width="match_parent"
            android:name="com.google.android.gms.maps.MapFragment"/>
    </FrameLayout>
</RelativeLayout>

and you can have your methods in your parent activity and call them from your fragments:

public void replaceFragment(Fragment fragment) {
    hideFrames();
    fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.YourId, fragment);
    fragmentTransaction.commit();
}

and it is called from each fragment attached to the activity like so:

// create new fragment
((MainActivity) getActivity()).replaceFragment(fragment);

Also:

There's a known issue with this

Fix issue #6584942 IllegalStateException: Failure saving state...

...active SuggestFragment{419494f0} has cleared index: -1

There were issues when the same fragment was removed and then added again before completely finishing the remove (such as due to a running animation).




回答2:


For the ones who want more information about that crash. There are confusions between getActivity().getSupportFragmentManager() / getChildFragmentManager() / getFragmentManager().

getActivity().getSupportFragmentManager() is the Activity FragmentManager. getChildFragmentManager() is my FragmentManager (my as the current Fragment) getFragmentManager() is my host FragmentManager (my as the current Fragment) and so my ParentFragment FragmentManager if ParentFragment not null, or my Activity FragmentManager.

So be sure to always use the same FragmentManager.

In the question, we can read:

mapFragment = (SupportMapFragment) this.getChildFragmentManager() .findFragmentById(R.id.map);

And

SupportMapFragment mapFragment = ((SupportMapFragment) getChildFragmentManager() .findFragmentById(R.id.map)); if(mapFragment != null) { FragmentManager fM = getFragmentManager(); fM.beginTransaction().remove(mapFragment).commit(); }

The MapFragment is never removed since we use our host FragmentManager to remove it and the ChildFragmentManager to find it.




回答3:


You are removing wrong Fragment(Map Fragment), You have to remove "ClinicFragment" Fragment.



来源:https://stackoverflow.com/questions/34480430/failure-saving-state-active-supportmapfragment-has-cleared-index-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!