App crash by “back” to maps fragment

2019-07-18 12:19发布

问题:

I working on my first app and got problems with the "back" function.

When i open the app an click in the menu to another fragment (2,3 or 4) and i push the back button the app crashes. When i start the app and click 2 > 3 > 4 (in this order) in the menu and push the back button i go back to 3 > 2 > crash. The app crashes when i go back to the mainFragment which contains a google map.

I think my problem has something to do with the googlemap in this fragment (the fragment to navigate back to) because when i set 2 enters before the error line in the xml of that view and run again, the error line number is +2. and when i comment out this fragment the back button works fine.

By navigate to an new fragment i call:

fragmentTransaction.replace(R.id.fr_content_container, new NewsFragment()).addToBackStack(null).commit();

The error i get is

04-01 14:26:39.679 19054-19054/aaeu.app E/AndroidRuntime: FATAL EXCEPTION: main
                                                          Process: aaeu.app, PID: 19054
                                                          android.view.InflateException: Binary XML file line #7: Binary XML file line #7: Error inflating class fragment
                                                              at android.view.LayoutInflater.inflate(LayoutInflater.java:539)
                                                              at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
                                                              at aaeu.app.presentationlayer.tab_AlertMapsOverview.onCreateView(mapsFragment.java:52)
                                                          .....................

The XML of the mapsFragment is:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <fragment
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="2"
            android:name="com.google.android.gms.maps.SupportMapFragment"
            android:id="@+id/mapwhere" />
    </RelativeLayout>

The code of the map fragment is:

    private SupportMapFragment mMapFragment;
    private AlertManager mAlertManager;
    private GoogleMap mGoogleMap;
    HashMap<Marker, Alert> mMarkerMap;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAlertManager = new AlertManager(getContext());
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.overview_maps_alert_tab, container, false);
        ButterKnife.bind(this, view);

        loadMap();

        return view;
    }

    private void loadMap() {
        mMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.mapwhere);
        if (mMapFragment == null) {
            FragmentManager fragmentManager = getFragmentManager();
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            mMapFragment = SupportMapFragment.newInstance();
            fragmentTransaction.replace(R.id.mapwhere, mMapFragment).commit();
        }

        if (mMapFragment != null) {
            mMapFragment.getMapAsync(new OnMapReadyCallback() {
                @Override
                public void onMapReady(GoogleMap googleMap) {
                    if (googleMap != null) {
                        googleMap.getUiSettings().setAllGesturesEnabled(true);

                        LatLng marker_latlng = new LatLng(55.042684, 14.125549);

                        CameraPosition cameraPosition = new CameraPosition.Builder().target(marker_latlng).zoom(3.0f).build();
                        CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition);
                        googleMap.moveCamera(cameraUpdate);

                        setGoogleMap(googleMap);
                    }
                }
            });
        }
    }

    private void setGoogleMap(GoogleMap googleMap) {
        this.mGoogleMap = googleMap;
    }


    // This method is called by the asynctask who downloads the alerts
    @Override
    public void UpdateAlerts(List<Alert> alerts) {

        mMarkerMap = new HashMap<Marker, Alert>();
        try {
        for (Alert alert : alerts) {
            MarkerOptions marker = new MarkerOptions();
            marker.position(alert.Location.get(0));
            marker.title(alert.GetFullName());

            Marker m = mGoogleMap.addMarker(marker);
            mMarkerMap.put(m, alert);
        }


            mGoogleMap.setOnMarkerClickListener(
                    new GoogleMap.OnMarkerClickListener() {
                        @Override
                        public boolean onMarkerClick(Marker marker) {
                            startDetailView(marker);
                            return false;
                        }
                    }
            );
        }
        catch (NullPointerException e)
        {
            Log.i("tab_AlertMapsOverview","No missings to create markers for or set clicklisteners on. Are there missings in the configured Areas?");
        }
    }

Near this problem i have a little question too. When i have 3 fragments, 1, 2 and 3. When i (for example) start in activity 1 and navigate to 2 > 3 > 2 > 3 i need to push 4 times back to come back in 1. Is it posible to use a kind of "tree" system for back navigation. so i allways go up 1 level? Maybe this clears up what i mean.

I think also the current situation is far from optimal becouse the fragments are still active in RAM? or are i'am wrong?

回答1:

I too had the same Issue. After wasting a lot of time searching for the solution, what i finally did was, I removed fragment tag from xml. Put a FrameLayout there and whenever I want to add that fragment, I would add it with fragment transaction. That worked out for me.

The cause for the issue is, whenever onCreateView() for that fragment is called, the xml file will be inflated which will inflate the fragment. This will lead to multiple fragments with the same id which causes this exception.