2012-12-16 10 views
14

Uruchamianie nieznacznie zmodyfikowanego przykładu Map Google powoduje wyświetlenie BadParcelableException w kodzie Map Google. Klasa LatLng jest paczkowana, ale nie można jej znaleźć. Wygląda na to, że kod Mapy Google próbuje rozpakować obiekt, który nie został przez niego spakowany. W jakich przypadkach problem?BadParcelableException w kodzie mapy Google

package com.example.mapdemo; 

import com.google.android.gms.maps.GoogleMap; 
import com.google.android.gms.maps.MapView; 
import com.google.android.gms.maps.model.LatLng; 
import com.google.android.gms.maps.model.MarkerOptions; 

import android.os.Bundle; 

public class RawMapViewDemoActivity extends android.support.v4.app.FragmentActivity { 
    private MapView mMapView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.raw_mapview_demo); 

     mMapView = (MapView) findViewById(R.id.map); 
     mMapView.onCreate(savedInstanceState); 
    } 

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

     outState.putParcelable("marker", new LatLng(0, 0)); 
    } 

    @Override 
    protected void onRestoreInstanceState(Bundle savedInstanceState) { 
     super.onRestoreInstanceState(savedInstanceState); 

     LatLng ll = savedInstanceState.getParcelable("marker"); 
    } 
} 

...

FATAL EXCEPTION: main 
java.lang.RuntimeException: Unable to start activity 
    ComponentInfo{com.example.mapdemo/com.example.mapdemo.RawMapViewDemoActivity}: 
    android.os.BadParcelableException: ClassNotFoundException when unmarshalling: 
    com.google.android.gms.maps.model.LatLng 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647) 
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663) 
    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:2832) 
    at android.app.ActivityThread.access$1600(ActivityThread.java:117) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935) 
    at android.os.Handler.dispatchMessage(Handler.java:99) 
    at android.os.Looper.loop(Looper.java:130) 
    at android.app.ActivityThread.main(ActivityThread.java:3683) 
    at java.lang.reflect.Method.invokeNative(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:507) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
    at dalvik.system.NativeStart.main(Native Method) 

Caused by: android.os.BadParcelableException: 
ClassNotFoundException when unmarshalling: com.google.android.gms.maps.model.LatLng 
    at android.os.Parcel.readParcelable(Parcel.java:1958) 
    at android.os.Parcel.readValue(Parcel.java:1846) 
    at android.os.Parcel.readMapInternal(Parcel.java:2083) 
    at android.os.Bundle.unparcel(Bundle.java:208) 
    at android.os.Bundle.getBundle(Bundle.java:1078) 
    at com.google.android.gms.maps.internal.MapStateHelper 
     .getParcelableFromMapStateBundle(MapStateHelper.java:41) 
    at maps.y.ae.a(Unknown Source) 
    at maps.y.bm.onCreate(Unknown Source) 
    at com.google.android.gms.maps.internal.IMapViewDelegate$Stub 
     .onTransact(IMapViewDelegate.java:66) 
    at android.os.Binder.transact(Binder.java:279) 
    at com.google.android.gms.maps.internal.IMapViewDelegate$a$a 
     .onCreate(Unknown Source) 
    at com.google.android.gms.maps.MapView$b.onCreate(Unknown Source) 
    at com.google.android.gms.internal.c$3.a(Unknown Source) 
    at com.google.android.gms.internal.i.b(Unknown Source) 
    at com.google.android.gms.maps.MapView$a.a(Unknown Source) 
    at com.google.android.gms.maps.MapView$a.a(Unknown Source) 
    at com.google.android.gms.internal.c.a(Unknown Source) 
    at com.google.android.gms.internal.c.onCreate(Unknown Source) 
    at com.google.android.gms.maps.MapView.onCreate(Unknown Source) 
    at com.example.mapdemo.RawMapViewDemoActivity 
     .onCreate(RawMapViewDemoActivity.java:40) 
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611) 
    ... 12 more 
+0

gdzie jest linia RawMapViewDemoActivity.java:40 w kodzie –

+0

mMapView.onCreate (savedInstanceState); Przepraszam, zredagowałem kod dla zwięzłości. – user1611728

+0

jeśli skomentujesz linię 'mMapView.onCreate (savedInstanceState); ', to czy działa, czy nie? –

Odpowiedz

0

znalazłem obejście (troche). W miejscu, w którym to się dzieje, po prostu spróbuj zrobić to po raz drugi. Zawsze chwyta Wyjątek i po raz drugi problem nie zdarza się w tym miejscu. To działało dla mnie.

try { 
    mapIntent.putExtra(Intents.EXTRA_LATLNG, new LatLng(
     store.getLatitude(), store.getLongitude())); 
} catch (BadParcelableException e) { 
    mapIntent.putExtra(Intents.EXTRA_LATLNG, new LatLng(
     store.getLatitude(), store.getLongitude())); 
} 
0

Znalazłem prostsze obejście tego. Podając swój fragment lub ładowarka Klasa aktywności do wiązki przed perfoming żadnych operacji jako takie:

savedInstanceState.setClassLoader(getClass().getClassLoader()); 

nie wydają się działać, gdy przechodząc bezpośrednio do MapFragment lub MapView za onCreateView lub onCreate chociaż, więc musisz ręcznie muszą rozłożyć mapę CameraPosition i przekazać pakiet zerowy do tych funkcji.

+0

Masz przykład opisanego rozwiązania? – speedynomads

12

Próbowałem dwóch poprzednich odpowiedzi bez powodzenia, ale znalazłem innego rozwiązania:

Podczas zapisywania stanu, należy uważać, aby przekazać połączenie MapView.onSaveInstanceState przed dodaniem swoich danych do Bundle (zrobiłeś to dobrze) :

@Override 
public void onSaveInstanceState(Bundle outState) { 

    // Forward the call BEFORE adding our LatLng array, else it will crash : 
    _mapView.onSaveInstanceState(outState); 

    // Put your Parcelable in the bundle: 
    outState.putParcelableArray("myLatLng", new LatLng(0, 0)); 
} 

Podczas przywracania stanu w onCreate/onRestore sprawdzić, czy pakiet nie jest null, jeśli tak, to dostać paczkę, a następnie wyjmij ją z wiązki przed przekazaniem połączenia:

@Override 
public void onCreate(Bundle savedInstanceState) { 

    // If the bundle is not null, get your Parcelable : 
    LatLng myLatLng = null; 
    if(savedInstanceState != null) { 

     myLatLng = (LatLng) savedInstanceState.getParcelable("myLatLng"); 

     // Remove your Parcelable from the bundle, else it will crash : 
     savedInstanceState.remove("myLatLng"); 
    } 

    // Forward the call : 
    _mapView.onCreate(savedInstanceState); 
    setUpMapIfNeeded(); 
} 
+0

Ta poprawka działa dla mnie! thx – Sulfkain

+0

Uratujesz mi życie! :) – IlyaEremin

0

Miałem także wyjątek BadParcelableException, gdy opuszczałem moją aplikację (FragmentActivity z kartami i Fragment w każdej karcie). Rozwiązałem to przez wywołanie pierwszego mapmpvMap.onSaveInstanceState(outState); a następnie super.onSaveInstanceState(outState);

3

Ten problem jak zostało złożone w dniu code.google.com here w przypadku byłoby chcesz go gwiazdą.

W międzyczasie udało mi się obejść ten problem, po prostu dodając moją paczkę do paczki przed dodaniem jej do ostatecznej paczki z pakietem onSaveInstanceState. Działa to, ponieważ Pakiet jest znaną klasą przez wewnętrzną klasę ClassLoader MapView.

Stworzyłem dwie bardzo małe metody, aby to zrobić dla mnie. Oto kod

Zmodyfikowałem kod w jednym z poprzednich postów, aby użyć mojego tymczasowego rozwiązania. Oto, jak go używam.

@Override 
public void onSaveInstanceState(Bundle outState) { 

    // Forward the call BEFORE adding our LatLng array, else it will crash : 
    _mapView.onSaveInstanceState(outState); 

    // Put your Parcelable in the bundle: 
    bundleParcelable("myLatLng", outState, new LatLng(0, 0)); 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    // Forward the call : 
    _mapView.onCreate(savedInstanceState); 

    LatLng myLatLng = null; 
    if(savedInstanceState != null) { 
     // Extract your Parcelable 
     myLatLng = (LatLng) unbundleParcelable("myLatLng", savedInstanceState); 
    } 

    setUpMapIfNeeded(); 
} 

Powinno to działać w przypadku każdej niestandardowej przesyłki, której używasz w projekcie.

+0

Doskonale, twoja odpowiedź zadziałała. –

+0

Cóż, cieszę się, że kod był dla kogoś użyteczny. Twoje zdrowie! –

31

Po prostu, aby dodać do istniejących odpowiedzi tutaj, usunąłem moje paczki z zapisanego stanu przed wywołaniem mapView.onCreate i działało dobrze.

Jednak po dodaniu ViewPager do mojego Fragment nie zdawałem sobie sprawy, że BadParcelableException powrócił i kod wykonał go do produkcji. Okazuje się, że ViewPager zapisuje również swój stan, a ponieważ jest częścią Biblioteki Wsparcia, Google Map nie może znaleźć klasy, aby ją rozpakować.

Więc zdecydowałem się na odwrócenie tego procesu, zamiast usuwania Przesyłek z Pakietu, o którym wiedziałem, zdecydowałem się utworzyć nowy Pakiet do kopiowania mapy tylko na podstawie stanu mapy.

private final static String BUNDLE_KEY_MAP_STATE = "mapData"; 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    // Save the map state to it's own bundle 
    Bundle mapState = new Bundle(); 
    mapView.onSaveInstanceState(mapState); 
    // Put the map bundle in the main outState 
    outState.putBundle(BUNDLE_KEY_MAP_STATE, mapState); 
    super.onSaveInstanceState(outState); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.fragment_map, container, false); 
    mapView = (MapView) view.findViewById(R.id.mapView); 
    mapView.getMapAsync(this); 

    Bundle mapState = null; 
    if (savedInstanceState != null) { 
     // Load the map state bundle from the main savedInstanceState 
     mapState = savedInstanceState.getBundle(BUNDLE_KEY_MAP_STATE); 
    } 

    mapView.onCreate(mapState); 
    return view; 
} 
+0

Wygląda na to, że mamy do czynienia z bieżącym wątkiem: https://code.google.com/p/gmaps-api-issues/issues/detail?id=6237#c9 To jest rozsądna odpowiedź i działa dobrze dla mnie –

+0

Dziękuję bardzo! Działa doskonale! –