2012-07-08 11 views
31

widzę następujący błąd w moich Android raportów o awariach:

android.os.BadParcelableException: ClassNotFoundException when unmarshalling: android.support.v4.view.ViewPager$SavedState 
at android.os.Parcel.readParcelable(Parcel.java:1971) 
at android.os.Parcel.readValue(Parcel.java:1859) 
at android.os.Parcel.readSparseArrayInternal(Parcel.java:2128) 
at android.os.Parcel.readSparseArray(Parcel.java:1581) 
at android.os.Parcel.readValue(Parcel.java:1916) 
at android.os.Parcel.readMapInternal(Parcel.java:2099) 
at android.os.Bundle.unparcel(Bundle.java:223) 
at android.os.Bundle.getSparseParcelableArray(Bundle.java:1225) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:806) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1083) 
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:635) 
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1431) 
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431) 
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:160) 
at android.support.v4.view.ViewPager.populate(ViewPager.java:895) 
at android.support.v4.view.ViewPager.populate(ViewPager.java:772) 
at android.support.v4.view.ViewPager.completeScroll(ViewPager.java:1539) 
at android.support.v4.view.ViewPager.computeScroll(ViewPager.java:1422) 
at android.view.ViewGroup.drawChild(ViewGroup.java:3028) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788) 
at android.view.ViewGroup.drawChild(ViewGroup.java:3184) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788) 
at android.view.ViewGroup.drawChild(ViewGroup.java:3184) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788) 
at android.view.ViewGroup.drawChild(ViewGroup.java:3184) 
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2788) 
at android.view.View.draw(View.java:11017) 
at android.widget.FrameLayout.draw(FrameLayout.java:450) 
at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2175) 
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2234) 
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1810) 
at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2695) 
at android.os.Handler.dispatchMessage(Handler.java:99) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:4977) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:511) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
at dalvik.system.NativeStart.main(Native Method) 

Wydaje się zdarzyć sporadycznie po wznowieniu działalności. Nie uzyskuję bezpośredniego dostępu do klasy SavedState w żadnym kodzie.

+0

Mam podobny problem, rzeczywiście, śmiem twierdzić, że jest identyczny. Zaczęło się to dziać po przełączeniu 'FragmentPagerAdapter' na' FragmentStatePagerAdapter. Czy wiesz, dlaczego tak się dzieje? P.D: Powinieneś spróbować dołączyć swój kod do pytań przepełnienia stosu. – mdelolmo

+1

W witrynie code.google.com występuje błąd: http://code.google.com/p/android/issues/detail?id=37484 – JWGS

+0

@ user379806, w tym raporcie o błędzie znajduje się obejście faktycznie rozwiązuje problem. Wygląda na to, że to błąd Androida. – mdelolmo

Odpowiedz

26

Miałem ten sam błąd i oto, co zrobiłem.

Mój problem pochodzi z użycia ViewPagera z FragmentStatePagerAdapter. Wewnątrz jednego z Fragmentów z ViewPagera miał inny ViewPager. Pager z drugim widokiem spowodował ten rzadki błąd. Nawet z adapterem lub bez niego.

Rozwiązaniem było po prostu ustawienie setSaveEnabled (false); na drugiej ViewPager.

+3

+1 To właśnie mi się przydarzyło ViewPager w innym ViewPager podając błąd, dzięki za twoje proste rozwiązanie! Niesamowity Android do dziś nie rozwiązał tego błędu. – pvalle

14

następujące rozwiązanie pracował dla mnie:

package android.support.v4.app; 

import android.os.Bundle; 
import android.view.ViewGroup; 

public abstract class FixedFragmentStatePagerAdapter extends FragmentStatePagerAdapter { 

    public FixedFragmentStatePagerAdapter(FragmentManager fm) { 
    super(fm); 
    } 

    @Override 
    public Object instantiateItem(ViewGroup container, int position) { 
    Fragment f = (Fragment)super.instantiateItem(container, position); 
    Bundle savedFragmentState = f.mSavedFragmentState; 
    if (savedFragmentState != null) { 
     savedFragmentState.setClassLoader(f.getClass().getClassLoader()); 
    } 
    return f; 
    } 

} 

z http://code.google.com/p/android/issues/detail?id=37484#c1

+0

Czy możesz dodać podsumowanie tej odpowiedzi? To sprawiłoby, że ta odpowiedź byłaby przydatna nawet wtedy, gdyby link kiedykolwiek się zmienił lub treść została usunięta, edytowana lub cokolwiek innego. –

+0

Co to jest mSavedFragmentState? Nie można go znaleźć w obiekcie Fragment w moim projekcie. – tasomaniac

+1

To chronione pole. Musisz umieścić swój adapter w paczce android.support.v4.app, aby uzyskać do niego dostęp ... – Kuno

8

Jeśli nie chcesz, aby to źródło w pakiecie v4 można zadeklarować „naprawić” bezpośrednio w adapterze

@Override 
    public Object instantiateItem(ViewGroup container, int position) { 
     final Object fragment = super.instantiateItem(container, position); 
     try { 
      final Field saveFragmentStateField = Fragment.class.getDeclaredField("mSavedFragmentState"); 
      saveFragmentStateField.setAccessible(true); 
      final Bundle savedFragmentState = (Bundle) saveFragmentStateField.get(fragment); 
      if (savedFragmentState != null) { 
       savedFragmentState.setClassLoader(Fragment.class.getClassLoader()); 
      } 
     } catch (Exception e) { 
      Log.w("CustomFragmentStatePagerAdapter", "Could not get mSavedFragmentState field", e); 
     } 
     return fragment; 
    } 
+1

+1, chociaż lepiej nie łączyć wyjątku z komunikatem logu (ponieważ nie jest to prawdopodobnie wewnętrznie nazywane 'e.toString() 'zwróci coś użytecznego), ale przekazuje osobno:' Log.w ("Niestandardowe ...", "Nie można ...", e) '. –

+0

@NikitaBosik dzięki, naprawione. –

2

Odpowiedź może być spóźniona. Używam FragmentPagerAdapter zamiast używać FragmentStatePagerAdapter. Zrobiłem dla mnie urok!

+2

To nie działa konsekwentnie we wszystkich systemach operacyjnych Android. To zawiesza się w niektórych systemach operacyjnych. Zobaczysz to, gdy zaczniesz testować na wielu urządzeniach i wersjach systemu operacyjnego. –

7

w Aktywności/fragment, należy wykonać następujące czynności:

public void onSaveInstanceState(Bundle outState){ 
    //This MUST be done before saving any of your own or your base class's  variables 
    final Bundle mapViewSaveState = new Bundle(outState); 
    mapView.onSaveInstanceState(mapViewSaveState); 
    outState.putBundle("mapViewSaveState", mapViewSaveState); 
    //Add any other variables here. 
    super.onSaveInstanceState(outState); 
} 

public void onCreate(Bundle savedInstanceState){ 
    super.onCreate(savedInstanceState); 
    final Bundle mapViewSavedInstanceState = savedInstanceState != null ?  savedInstance.getBundle("mapViewSaveState") : null; 
mapView.onCreate(mapViewSavedInstanceState); 
//.... 
} 

źródło: https://code.google.com/p/gmaps-api-issues/issues/detail?id=6237

lub inny roztwór:

map.onCreate (savedInstanceState);

to:

map.onCreate (zerowy);

+0

To jest całkowicie niepowiązane –

+0

Miałem do czynienia z tym samym wyjątkiem w widoku mapy, i dowiedzieć się tego rozwiązania i jego pracy dla mnie grt teraz. – Mubarak

+0

A mój MapView nie działał poprawnie. – Malder

Powiązane problemy