Failure save state: Active SupportMapFragment {} cleared index: -1

I use supportMapFragment inside the fragment, so I use this.getChildFragmentManager() , if it is wrong, please help 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 magazine

 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 mistake in order to try to delete the map fragment, but it can not find the link

My attempts

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

2- Kill the fragment in onStop.

but all this will not help me fix my problem, anyone can explain to me why I miss

+5
source share
3 answers

I do not use public static ClinicFragment newInstance()

I use fragments attached to example actions.

 public class MyFragment extends Fragment 

I don’t understand why you are killing a fragment of your map. I never had to do this, and simply allowed the life cycle of natural activity to control the destruction of most things.

You also call the super onDestroy method before your killOldMap, which means that the order of tasks killed in the super method will be called before the killOldMap method. It can also cause resources to freeze without tied activities.

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

So, there are several ways to manage this:

Deleting a fragment will destroy the fragment without using the kill method:

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

It uses fragmentTransaction.replace(R.id.yourId, fragment )

Personally, I like the idea of ​​using frameelayout in my activity layout, and then switching the visibility between the map and another fragment, I don’t destroy the map, there it comes back with any coordinates I'm looking for, It doesn’t harm if I manage location services well. This is a design choice that I use and by no means the law.

I manage any location calls with fragment visibility within this frame. Creating a custom method:

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

In this way, frameelayout controls 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 use your methods in your parenting 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 such activity:

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

also:

There is a known problem with this

Fix Problem # 6584942 IllegalStateException: Failed Status ...

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

There were problems when the same fragment was deleted and then added again before the deletion is complete (for example, to a running animation).

+4
source

For those who want more information about this failure. There is confusion between getActivity().getSupportFragmentManager() / getChildFragmentManager() / getFragmentManager() .

getActivity().getSupportFragmentManager() is a FragmentManager function. getChildFragmentManager() is my FragmentManager (mine as the current fragment) getFragmentManager() is my host FragmentManager (mine as the current fragment) and therefore my ParentFragment FragmentManager if ParentFragment is not null or my Activity FragmentManager.

Therefore, be sure to use the same FragmentManager.

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

MapFragment is never deleted, since we use our host FragmentManager to remove it and ChildFragmentManager to find it.

0
source

You delete the wrong fragment (map fragment), you need to delete the "ClinicFragment" fragment.

0
source

Source: https://habr.com/ru/post/1239293/


All Articles