https://stackoverflow.com/a/8745966/72437 and https://stackoverflow.com/a/20073367/72437 have well explanation on why such crash happens.
https://stackoverflow.com/a/14866690/72437 also has a example on how we can workaround with this.
I would like to provide code examples, to help better understanding.
Let me demonstrate an example on why such incident fails sometimes.
An example to demonstrate why such crash happens
package javaapplication12;
/**
*
* @author yccheok
*/
public class JavaApplication12 {
public static class Parcelable {
}
public static class Uri extends Parcelable {
}
public static Parcelable[] getParcelableArrayExtraDuringLowMemoryRestoration() {
// The Android system has no way to know it needs to create Uri[],
// during low memory restoration process.
Parcelable[] parcelables = new Parcelable[3];
for (int i=0; i<parcelables.length; i++) {
parcelables[i] = new Uri();
}
return parcelables;
}
public static Parcelable[] getParcelableArrayExtra() {
// The Android system has enough information that it needs to create Uri[]
Uri[] temp = new Uri[3];
for (int i=0; i<temp.length; i++) {
temp[i] = new Uri();
}
Parcelable[] parcelables = temp;
return parcelables;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// OK
{
// true
System.out.println(getParcelableArrayExtra() instanceof Uri[]);
Uri[] uris = (Uri[])getParcelableArrayExtra();
for (Uri uri : uris) {
System.out.println(uri);
}
}
// Crash!
{
// false
System.out.println(getParcelableArrayExtraDuringLowMemoryRestoration() instanceof Uri[]);
// ClassCastException.
Uri[] uris = (Uri[])getParcelableArrayExtraDuringLowMemoryRestoration();
for (Uri uri : uris) {
System.out.println(uri);
}
}
}
}
An example to demonstrate on how we can fix this
package javaapplication12;
/**
*
* @author yccheok
*/
public class JavaApplication12 {
public static class Parcelable {
}
public static class Uri extends Parcelable {
}
public static Parcelable[] getParcelableArrayExtraDuringLowMemoryRestoration() {
// The Android system has no way to know it needs to create Uri[],
// during low memory restoration process.
Parcelable[] parcelables = new Parcelable[3];
for (int i=0; i<parcelables.length; i++) {
parcelables[i] = new Uri();
}
return parcelables;
}
public static Parcelable[] getParcelableArrayExtra() {
// The Android system has enough information that it needs to create Uri[]
Uri[] temp = new Uri[3];
for (int i=0; i<temp.length; i++) {
temp[i] = new Uri();
}
Parcelable[] parcelables = temp;
return parcelables;
}
private static Uri[] safeCastToUris(Parcelable[] parcelables) {
if (parcelables instanceof Uri[]) {
return (Uri[])parcelables;
}
int length = parcelables.length;
Uri[] uris = new Uri[length];
System.arraycopy(parcelables, 0, uris, 0, length);
return uris;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// OK
{
Uri[] uris = safeCastToUris(getParcelableArrayExtra());
for (Uri uri : uris) {
System.out.println(uri);
}
}
// OK too!
{
Uri[] uris = safeCastToUris(getParcelableArrayExtraDuringLowMemoryRestoration());
for (Uri uri : uris) {
System.out.println(uri);
}
}
}
}