No entiendo por qué se produce esta ClassCastException

// Application ... Intent i = new Intent(); i.putExtra(EXTRA_FILE_UPLOAD_URIS, mGalleryAdapter.getItems()); Uri[] getItems() { return mItems; } // Service ... intent.getParcelableArrayExtra(EXTRA_FILE_UPLOAD_URIS); //works, returns Parcelable[] Uri[] uris = (Uri[])intent.getParcelableArrayExtra(EXTRA_FILE_UPLOAD_URIS); // ... Breaks with ClassCastException 

¿Por qué se rompe el elenco a Uri[] , cuando Uri es Parcelable ?

Desafortunadamente no hay manera de lanzar como eso para arrays en Java . Tendrá que iterar su matriz y lanzar cada objeto individualmente.

La razón de esto es el tipo de seguridad, la JVM simplemente no puede garantizar que el contenido de su matriz puede ser lanzado a Uri, sin tener que iterar a través de ellos, por lo que tiene que iterarlos y lanzarlos individualmente.

Básicamente, debido a que Parcelable podría ser heredado por otros objetos, no hay garantía de que la matriz sólo contiene objetos Uri . Sin embargo el lanzamiento a un supertipo trabajaría desde entonces la seguridad del tipo sería aceptable.

Utilice este método, funciona para mí.

 Parcelable[] ps = getIntent().getParcelableArrayExtra(); Uri[] uri = new Uri[ps.length]; System.arraycopy(ps, 0, uri, 0, ps.length); 

Las matrices tienen comportamiento polimórfico – sólo los tipos genéricos no tienen.

Es decir, si Uri implementa Parcelable entonces

puedes decir:

 Parcelable[] pa = new Uri[size]; Uri[] ua = (Uri[]) pa; 

no puedes decir:

 List<Parcelable> pl = new ArrayList<Uri>(); 

Como se ve, podemos emitir pa nuevo a Uri[] . ¿Entonces cuál es el problema? Este ClassCastException ocurre cuando se ClassCastException tu aplicación y más tarde se recrea la matriz guardada. Cuando se vuelve a crear el tiempo de ejecución no sabe qué tipo de matriz ( Uri[] ) que era por lo que sólo crea un Parcelable[] y pone elementos en él. De ahí la ClassCastException cuando intenta convertirlo a Uri[] .

Tenga en cuenta que la excepción no sucede (teóricamente) cuando el proceso no se cancela y la matriz creada originalmente ( Uri[] ) se reutiliza entre las rondas de salvar / restaurar estado. Al igual que cuando cambia la orientación.

Sólo quería dejar claro por qué sucedió. Si desea una solución @ solo siempre una decente.

Aclamaciones

Creo que lo que está sucediendo es algo así:

 class Parent { } class MaleParent extends Parent { } class FemaleParent extends Parent { } 

Si el escenario es algo como lo anterior, lo siguiente fallará en tiempo de ejecución:

 Parent[] parents = new FemaleParent[]{}; MaleParent[] maleParents = (MaleParent[]) parents; 

Algo como sigue no plantea la excepción:

 Parent[] parents = new MaleParent[]{}; MaleParent[] maleParents = (MaleParent[]) parents; 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.