wbk727
wbk727

Reputation: 8408

Map fragment crashes on resume

I'm trying to display a map view fragment within a tab but for some reason whenever I flick the toggle switch and go to a different tab, the app crashes whenever I return to the tab containing the map. I looked at the onResume() code but I'm not sure what needs to change within the class.

public class FragmentCentralParkLocation extends android.support.v4.app.Fragment implements OnMapReadyCallback {

    public FragmentCentralParkLocation() {
        // Required empty constructor
    }

    GoogleMap mGoogleMap;
    MapView mMapView;

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

        mMapView = (MapView) v.findViewById(R.id.map_centralpark);
        mMapView.onCreate(savedInstanceState);
        mMapView.getMapAsync(this); //this is important

        SwitchCompat swt = (SwitchCompat) v.findViewById(R.id.switch_map_centralpark);
        swt.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if(isChecked){
                    boolean success = mGoogleMap.setMapStyle(new MapStyleOptions(getResources()
                            .getString(R.string.style_json)));    
                }else{
                    boolean success = mGoogleMap.setMapStyle(null);
                }
            }
        });



        return v;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
        mGoogleMap.getUiSettings().setZoomControlsEnabled(true);
        mGoogleMap.setBuildingsEnabled(true);
        mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

        // Add markers and move the camera
        LatLng knt_location = new LatLng(40.782893, -73.965422);
        mGoogleMap.addMarker(new MarkerOptions()
                .position(knt_location)
        );


        // Updates the location and zoom level of the MapView
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(40.782893, -73.965422), 18);
        mGoogleMap.animateCamera(cameraUpdate);
    }

    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

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

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }
}

Stage 1

enter image description here

Stage 2

enter image description here

Stage 3

enter image description here

Logcat

03-12 16:45:24.965 2328-2328/com.ustravel.parks E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                    Process: com.ustravel.parks, PID: 2328
                                                                                    java.lang.NullPointerException
                                                                                        at com.ustravel.parks.FragmentCentralParkLocation $1.onCheckedChanged(FragmentCentralParkLocation.java:49)
                                                                                        at android.widget.CompoundButton.setChecked(CompoundButton.java:127)
                                                                                        at android.support.v7.widget.SwitchCompat.setChecked(SwitchCompat.java:1062)
                                                                                        at android.widget.CompoundButton.onRestoreInstanceState(CompoundButton.java:381)
                                                                                        at android.view.View.dispatchRestoreInstanceState(View.java:12799)
                                                                                        at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2643)
                                                                                        at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2643)
                                                                                        at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2643)
                                                                                        at android.view.View.restoreHierarchyState(View.java:12777)
                                                                                        at android.support.v4.app.Fragment.restoreViewState(Fragment.java:475)
                                                                                        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1329)
                                                                                        at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
                                                                                        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
                                                                                        at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:757)
                                                                                        at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2355)
                                                                                        at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2146)
                                                                                        at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2098)
                                                                                        at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1979)
                                                                                        at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:626)
                                                                                        at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:166)
                                                                                        at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
                                                                                        at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:668)
                                                                                        at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:630)
                                                                                        at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:611)

onResume map result

enter image description here

Upvotes: 1

Views: 1344

Answers (1)

savepopulation
savepopulation

Reputation: 11921

I think you're trying to restore the state of your SwitchCompat before your GoogleMap is ready and initialized. Here I modified your code a little bit:

public class FragmentCentralParkLocation extends android.support.v4.app.Fragment implements OnMapReadyCallback {

    public FragmentCentralParkLocation() {
        // Required empty constructor
    }

    GoogleMap mGoogleMap;
    MapView mMapView;
    SwitchCompat swt;

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

        mMapView = (MapView) v.findViewById(R.id.map_centralpark);
        mMapView.onCreate(savedInstanceState);
        mMapView.getMapAsync(this); //this is important

        swt = (SwitchCompat) v.findViewById(R.id.switch_map_centralpark);

        return v;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap = googleMap;
        mGoogleMap.getUiSettings().setZoomControlsEnabled(true);
        mGoogleMap.setBuildingsEnabled(true);
        mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

        swt.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
               initMap(isChecked);
            }
        });

        initMap(swt.isChecked());

        // Add markers and move the camera
        LatLng knt_location = new LatLng(40.782893, -73.965422);
        mGoogleMap.addMarker(new MarkerOptions()
                .position(knt_location)
        );


        // Updates the location and zoom level of the MapView
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(40.782893, -73.965422), 18);
        mGoogleMap.animateCamera(cameraUpdate);
    }

    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

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

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }

    private void initMap(boolean isChecked){
          if(isChecked){
                    mGoogleMap.setMapStyle(new MapStyleOptions(getResources()
                            .getString(R.string.style_json)));    
                }else{
                    mGoogleMap.setMapStyle(null);
                }
    }
}

I hope this will help you.

Edit: If you still experience crashing, you can try to remove onCheckedChangeListener of SwitchCompat in onStop or onDestroy by trying the following code:

swt.setonCheckedChangeListener(null);

Upvotes: 3

Related Questions