MapFragment заблокирован или ошеломлен, когда приложение убито или состояние сохранено

У меня возникают проблемы с использованием MapFragment + ListFragment в действии, когда я использую метод show() и hide(), все работает нормально, но когда мое приложение находится в фоновом режиме и я возвращаюсь, я получаю ошеломленный или заблокированный GoogleMap, и Я не знаю, что делать, чтобы решить эту проблему. Единственное решение, которое у меня работает нормально, - это использование транзакций замены, но мне это не нравится, потому что в каждой транзакции мы должны инициировать все всплывающие подсказки на карте, и это не сохраняет ваше последнее местоположение камеры, так что... Я не знаю, что делать.

PS: я использую SherlockActionBar

Заранее спасибо:

Вот мой код:

Деятельность:

...
@Override
public void onCreate(Bundle savedInstanceState) {
    BugSenseHandler.initAndStartSession(this, "f8013578");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_route_place);
    setViews();
    setData();
    doStuff();
}

@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.route_place_list:
        analyticTracker.sendView("/RoutePlaceActivity/List");
        isMap = true;
        changeFragments();
        break;
    case R.id.route_place_map:
        analyticTracker.sendView("/RoutePlaceActivity/Home");
        isMap = false;
        changeFragments();
        break;
    default:
        break;
    }
}

@Override
public void onRouteMapPlaceClick(Place place) {
    goToDetails(place);
}

@Override
public void onRouteListPlaceClick(Place place) {
    goToDetails(place);
}

@Override
public void onShowMessage(String message, Message type) {
    showMessage(message, type);
}

...

private void setData() {
    route = getIntent().getExtras().getParcelable("route");
    analyticTracker = GoogleAnalytics.getInstance(this).getTracker(Config.GOOGLE_ANALYTICS_ID);

    final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    /*
     * If the activity is killed while in BG, it's possible that the
     * fragment still remains in the FragmentManager, so, we don't need to
     * add it again.
     */
    if (mapFragment == null) {
        Log.v("RoutePlaceActivity", "mapFragment = null");
        mapFragment = new RoutePlaceMapFragment();
        ft.add(R.id.route_place_container, mapFragment);
    }
    ft.hide(mapFragment);
    if (listFragment == null) {
        Log.v("RoutePlaceActivity", "listFragment = null");
        listFragment = RoutePlaceListFragment.newInstance();
        ft.add(R.id.route_place_container, listFragment);
    }
    ft.hide(listFragment);
    ft.commit();
}

private void doStuff() {
    changeFragments();
    sendItineraryPlacesRequest();
}

private void changeFragments() {
    final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    ft.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
    if (isMap) {
        ft.hide(listFragment);
        ft.show(mapFragment);
        switcherView.setDisplayedChild(VIEW_LIST);
    } else {
        ft.hide(mapFragment);
        ft.show(listFragment);
        switcherView.setDisplayedChild(VIEW_MAP);
    }
    ft.commit();
}

private void sendItineraryPlacesRequest() {
    ... {

        ...

        @Override
        public void onSuccess(JSONObject response) {
            super.onSuccess(response);
            Places places = JSONObjectAdapter.getPlaces(response);
            mapFragment.addPlaces(places);
            listFragment.addPlaces(places);
        }

        ...

    });

}

Фрагмент карты:

/********************* Constructors **********************/
...


/********************* Class Methods *********************/
...

@Override
public void onCreate(Bundle savedInstanceState) {
    Log.v(CLASS_TAG, "onCreate");
    super.onCreate(savedInstanceState);
    setData(savedInstanceState);
    setUpMapIfNeeded();
}

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

@Override 
public void onDestroyView() {
    ((ViewGroup)getView()).removeAllViews();
    super.onDestroyView();
}


/******************** Public Methods ********************/
public void addPlaces(Places places) {
    mMap.clear();
    placeMap.clear();
    Builder builder = new LatLngBounds.Builder();
    for (Place place : places) {
        LatLng placePos = new LatLng(place.getLatitude(), place.getLongitude());
        builder.include(placePos);
        Marker m = mMap.addMarker(new MarkerOptions().position(placePos).title(place.getName()).draggable(false));
        placeMap.put(m, place);
    }

    if (places.size() > 1) {
        final LatLngBounds bounds = builder.build();
        try {

        mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));

        } catch (Exception e) {
            // layout not yet initialized
            final View mapView = getView();
            if (mapView.getViewTreeObserver().isAlive()) {
                mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

                    @SuppressWarnings("deprecation")
                    @SuppressLint("NewApi")
                    // We check which build version we are using.
                    @Override
                    public void onGlobalLayout() {
                        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                            mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                        } else {
                            mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        }
//                          mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
                    }
                });
            }
        }

    } else if (places.size() != 0) {
        final CameraPosition cameraPosition = new CameraPosition.Builder().zoom(17).target(new LatLng(places.get(0).getLatitude(), places.get(0).getLongitude())).tilt(25).build();
        try {
            mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 4000, null);
        } catch (Exception e) {
            // layout not yet initialized
            final View mapView = getView();
            if (mapView.getViewTreeObserver().isAlive()) {
                mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

                    @SuppressWarnings("deprecation")
                    @SuppressLint("NewApi")
                    // We check which build version we are using.
                    @Override
                    public void onGlobalLayout() {
                        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                            mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                        } else {
                            mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                        }
                        mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 4000, null);
                    }
                });
            }
        }

    } else {
        myListener.onShowMessage("No se han encontrado sitios cercanos", Message.INFO);
    }
}




/******************** Private Methods ********************/
private void setData(Bundle savedInstanceState) {
    placeMap = new HashMap<Marker, Place>();
    mMap = null;
}

private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the map.
    if (mMap == null) {
        mMap = getMap();
        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap();
        }
    }
}

private void setUpMap() {
    mMap.setMyLocationEnabled(true);
    mMap.setOnInfoWindowClickListener(this);

//        mMap.setOnMarkerClickListener(this);

    UiSettings uiSettings = mMap.getUiSettings();
    uiSettings.setCompassEnabled(false);

    Places places = getArguments().getParcelable("places");
    if (places != null) {
        addPlaces(places);
    }
}

ListFragment (1)

MapFragment (1)

MapFragment (2)

Фрагмент списка (2)


person cesards    schedule 27.02.2013    source источник


Ответы (1)


Я также столкнулся с той же проблемой в новых картах API (Maps V2 Android). Но я решил это, переопределив методы onSaveInstance и onRestoreInstance в активности контейнера... и не вызывая super.onSaveInstance(). и super.onRestoreInstance().

Это всего лишь временный хак.. но я думаю, что вы будете работать с вашим прекрасным приложением..

person Sandeep Dhull    schedule 27.02.2013
comment
OMG... Я потратил часы и часы... где вы нашли это решение?? Большое спасибо... - person cesards; 27.02.2013
comment
@SandeepDhull Пишете ли вы какой-либо код внутри этих двух методов, public void onSaveInstanceState(Bundle iCicle) и public void onRestoreInstanceState(Bundle iCicle)? Это те методы, о которых вы говорите, верно? Спасибо. - person AlexAndro; 22.03.2013
comment
Да, код для сохранения некоторых данных в пакете... вместо вызова версии super. - person Sandeep Dhull; 24.03.2013