ClassNotFoundException reading a Serializable object in a class extending MapFragment in onSaveInstanceState
Asked Answered
C

1

9

I have a class extending the SupportMapFragment where i load some data from backend and display the Markers. I also have another fragment which i display the details corresponding to the selected marker on the map. I am displaying the details fragment below the map in portrait mode and side by side in landscape.

public class MapDisplayFragment extends SupportMapFragment {
private ArrayList<ShowLocation> locations = null;

public void onViewCreated(View view, Bundle savedInstanceState) {
    if (savedInstanceState != null) {
    locations = (ArrayList<ShowLocation>)savedInstanceState.getSerializable("LOCATIONS");
    }
}
@Override
public void onSaveInstanceState(Bundle outState) {
  if (outState == null) {
 outState = new Bundle();
  }
  outState.putSerializable("LOCATIONS", locations);
  super.onSaveInstanceState(outState);
}

I have a class which implements Serializable which is used in the derived map class. I use the onSaveInstanceState to store the object so that i dont have to retrieve the data from the backend again. but the app crashes with java.lang.RuntimeException: Parcelable encounteredClassNotFoundException reading a Serializable object when i flip the device.

public class ShowLocation implements Serializable {
    private String geoCodeLat = Constants.EMPTY_STRING;
    private String geoCodeLng = Constants.EMPTY_STRING;
    ....
    public String getGeoCodeLat() {
       return geoCodeLat;
    }
    public void setGeoCodeLat(String geoCodeLat) {
       this.geoCodeLat = geoCodeLat;
    }

    public String getGeoCodeLng() {
       return geoCodeLng;
    }

    public void setGeoCodeLng(String geoCodeLng) {
        this.geoCodeLng = geoCodeLng;
    }
    ....
}

I have defined the layout as follows:

<LinearLayout
        android:id="@+id/layoutMapData"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >

        <fragment
            android:id="@+id/mapFrag"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="0.5"
            class="com.test.appFragments.MapDisplayFragment" />

        <LinearLayout
            android:id="@+id/layoutDetails"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="0.5"
            android:visibility="gone" >
        </LinearLayout>
    </LinearLayout>

If anyone has come accross this issue or if there is a solution to this issue please help me out.

Counterbalance answered 30/1, 2013 at 19:43 Comment(2)
Post the code. Always post the code.Whish
Post the code, and the stack trace. Make this alaways.Philadelphia
T
13

Not sure why this is happenning. Looks like data is getting unmarshalling somewhere inside Google Play services and there is no information about our classes. Correct me if I'm wrong.

However, there is a workaround. Instead of saving your data into outState, save it to arguments bundle (which is also getting saved). Here is an example:

public MyFragment extends SupportMapFragment {

    private MapView mMapView;

    public MyFragment() {
        /*
         * We need to set bundle here.
         * Note, that if you're actually using arguments
         * then skip line below.
         */
        setArguments(new Bundle());
    }

    /* YOUR CODE HERE */

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mMapView.onSaveInstanceState(outState);

        /* I'm using Serializable, but you can use whatever you want */
        getArguments().putSerializable("yourfield", yourValue);
    }

    @Override
    public void onCreate(Bundle savedState) {
        super.onCreate(savedState);
        mMapView.onCreate(savedState);

        if(savedState != null) {
            yourValue = getArguments.getSerializable("yourField");
        }
    }

}
Trek answered 12/4, 2013 at 14:12 Comment(4)
Best answer I could find after a days of googling!Watts
How do you assign the mMapView field? I did not found a way to get the MapView from the SupportMapFragment. :(Inclination
@Inclination don't remember that anymore, it was 2 years ago :) It could even be that it was Maps v1. Now I'm using MapView directly, without a fragment, so this solution does not apply anymore.Trek
OK, thanks. I finally solved the issue, by not extending SupportMapFragment, just adding that with the FragmentManager.Inclination

© 2022 - 2024 — McMap. All rights reserved.