2012-07-08 20 views
31

estoy viendo el siguiente error en mis informes de fallos Android:

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) 

Parece que suceda de forma intermitente cuando se reanuda la actividad. No accedo directamente a la clase SavedState en ningún código.

+0

Estoy teniendo un problema similar, de hecho, me atrevo a decir que es idéntico. Comenzó a suceder cuando cambié mi 'FragmentPagerAdapter' a' FragmentStatePagerAdapter. ¿Sabias por qué estaba sucediendo eso? P.D: Debería intentar incluir algún código suyo en sus preguntas sobre desbordamiento de pila. – mdelolmo

+1

Hay un error en code.google.com relacionado con esto: http://code.google.com/p/android/issues/detail?id=37484 – JWGS

+0

@ user379806, en ese informe de error, hay una solución que en realidad resuelve el problema. Ciertamente parece ser un error de Android. – mdelolmo

Respuesta

26

Tuve el mismo error y esto es lo que hice.

Mi problema vino del uso de ViewPager con un FragmentStatePagerAdapter. Dentro de uno de los Fragmentos del ViewPager había otro ViewPager. Tener ese segundo buscapersonas causó este raro error. Incluso con o sin un adaptador.

La solución fue simplemente configurar setSaveEnabled (false); en el segundo ViewPager.

+3

+1 Esto me estaba pasando exactamente a ViewPager dentro de otra ViewPager dando el error, ¡gracias por su simple solución! Increíble Android hasta hoy no resolvió este error. – pvalle

14

Siguiendo solución funcionó para mí:

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; 
    } 

} 

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

+0

¿Puede agregar un resumen a esta respuesta? Eso haría que esta respuesta siga siendo útil incluso si el enlace cambia alguna vez o si el contenido se elimina o edita o lo que sea. –

+0

¿Qué es mSavedFragmentState? No se pudo encontrar en el objeto Fragment en mi proyecto. – tasomaniac

+1

Es un campo protegido. Tienes que poner tu adaptador en el paquete android.support.v4.app para acceder a él ... – Kuno

8

Si no desea incluir en el paquete de la fuente v4 se puede declarar el "arreglo" directamente en su adaptador

@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, aunque es mejor que no concatenar la excepción al mensaje de registro (ya que no es probable que se llame internamente 'e.toString() 'devolverá algo útil), pero páselo por separado:' Log.w ("Custom ...", "Could not ...", e) '. –

+0

@NikitaBosik gracias, arreglado. –

2

La respuesta puede ser tarde. Usé FragmentPagerAdapter en lugar de usar FragmentStatePagerAdapter. ¡Trabajó para mí como un encanto!

+2

Esto no funciona sistemáticamente en todos los sistemas operativos Android. Se bloquea en algunos sistemas operativos. Verá esto cuando comience a probar en múltiples dispositivos y versiones del sistema operativo. –

7

En su actividad/Fragmento, haga lo siguiente:

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); 
//.... 
} 

fuente: https://code.google.com/p/gmaps-api-issues/issues/detail?id=6237

u otra solución es:

map.onCreate (savedInstanceState);

a esto:

map.onCreate (null);

+0

Esto no tiene ninguna relación –

+0

Estaba enfrentando la misma excepción en la vista de mapa, y descubro esta solución y está funcionando para mí ahora. – Mubarak

+0

Y mi MapView no funcionó correctamente. – Malder

Cuestiones relacionadas