ClassNotFoundException en la clase serializable durante el inicio de la actividad

La puesta en marcha

Tengo una actividad que sólo anula onCreate (), onResume (), y onSaveInstanceState (). En onSaveInstanceState (), puse en un objeto serializable:

@Override public void onSaveInstanceState(Bundle state) { super.onSaveInstanceState(state); state.putSerializable("obj", myObj); // myObj is of class MyClass state.putLong("long", longVar); } 

MyClass era originalmente una clase interna dentro de la clase de actividad, pero para depurar, incluso lo moví a un archivo separado:

 public class MyClass implements Serializable { private static final long serialVersionUID = 0x98ED2F00; .... } 

Los pasos:

  1. Iniciar el programa de la manera habitual, se ejecuta bien.
  2. Haga clic en el botón Inicio para volver al Lanzador.
  3. Desde Eclipse, detenga el proceso desde el panel Dispositivo
  4. Inicie el programa de nuevo desde el Lanzador, esta vez tengo lo siguiente:

    Java.lang.RuntimeException: No se puede iniciar la actividad ComponentInfo {com.example.Reports}: java.lang.RuntimeException Parcelable encontró ClassNotFoundException leyendo un objeto serializable {name = com.example.MyClass}

    Causado por: java.lang.ClassNotFoundException: com.examp.MyClass en loader dalvik.System.PathClassLoader [.]

Pistas y Observaciones:

  1. La pista más importante es: si no guardo myObj en onSaveInstanceState (), entonces todo está bien. Y poner cualquier tipo primitivo en el Bundle está bien, pero no mis objetos.

  2. La excepción es lanzada fuera de mi código, sucedió entre onCreate () y onResume (). Sucedió dentro de Android.

  3. El nombre de clase en el mensaje de error es correcto: com.example.MyClass. Originalmente se trataba de una clase interna dentro de la actividad, pero para aislar el problema, lo trasladé a un archivo independiente, en vano.

  4. Creo que la implementación de Serializable es correcta, ya que puede ser serializada a / desde un archivo en otras partes del programa.

¿Alguien tiene una idea de una posible causa de esto? ¡Muy apreciado! (Lo siento, no puedo poner código detallado aquí, porque todo está entrelazado aquí y allá. Sólo puedo aislar tanto como sea posible.)

OK, creo que encontré una solución a este problema.

Resultó que si el parámetro savedInstanceState pasó a onCreate () no es nulo, entonces uno DEBE deserializar cualquier objeto contenido en ese Bundle. No sé por qué, pero así es como me libré del problema. Originalmente mi código en onCreate () tiene la lógica de que bajo algunas condiciones, desatiendo el savedInstanceState. Ahora lo que hago es siempre y cuando no sea nulo, solo deserializaré todo, entonces, basado en otras condiciones, decido si los uso o no.

Hasta ahora funciona bien. Pero no tengo idea acerca de:

  1. ¿Por qué tengo que deserializarlos, y si no lo hago, la excepción sucede?

  2. ¿Qué estaba haciendo Android para deserializar mis cosas que puse en savedInstanceState? Quiero decir, entiendo que Android puede haber puesto alguna información para su propio uso, pero ¿por qué viene y trata de deserializar mis cosas? ¿Si sabe que no sabe cómo usarlos?

He estado luchando contra este mismo problema y la forma en que acabé resolviéndolo fue implementar Parceable lugar de Serializable en la clase que estaba escondida en el Bundle.

Fui capaz de reproducir de forma fiable el bloqueo mediante el uso de la aplicación DevTools en el emulador (no parece funcionar en un dispositivo real) y cambiar la Development Settings > Immediately destroy activities que se verán. Cambiar mi clase personalizada a Parceable y cambiar a putParcelable en mi onSaveInstanceState parecía arreglar el problema.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.