Android ClassCastException con el tipo en blanco
Estoy obteniendo un comportamiento extraño, y supongo que estoy buscando más una explicación que una solución (aunque la solución es bienvenida también!).
Aquí está el código:
- ¿Cuál es la mejor manera de crear archivos temporales en Android?
- Java.lang.RuntimeException: No se puede instanciar la aplicación, java.lang.ClassNotFoundException:
- Org.eclipse.swt.SWTException: "Widget está eliminado" al intentar abrir AndroidManifest.xml
- Android obtiene diferencia en milisegundos entre dos fechas
- Android M Permisos: onRequestPermissionsResult () no se llama
PackageManager pm = context.getPackageManager(); List<PackageInfo> pkgList = pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES); if (pkgList == null) return null; for (PackageInfo pkgInfo : pkgList) { ApplicationInfo appInfo = pkgInfo.applicationInfo; // do some stuff, doesn't modify pkgInfo or appInfo or pkgList }
Y en algunas ocasiones, estoy recibiendo registros de errores con:
Java.lang.ClassCastException: no se puede convertir en android.content.pm.PackageInfo
Informó para la línea:
for (PackageInfo pkgInfo : pkgList)
La parte extraña es que, normalmente, ClassCastException
generalmente se parece a (AFAIK):
Java.lang.ClassCastException : foo.bar.ClassA no se puede convertir en foo.bar.ClassB
Sin embargo, el error que estoy viendo está mostrando en blanco para la primera parte.
Decidí investigar un poco, y leer algo a lo largo de las líneas de que podría suceder si la función que está devolviendo la lista interna lanzó la lista de objetos erróneos y lo devolvió o algo así. Así que miré:
ApplicationPackageManager.getInstalledPackages()
@SuppressWarnings("unchecked") @Override public List<PackageInfo> getInstalledPackages(int flags) { try { final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>(); PackageInfo lastItem = null; ParceledListSlice<PackageInfo> slice; do { final String lastKey = lastItem != null ? lastItem.packageName : null; slice = mPM.getInstalledPackages(flags, lastKey); lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR); } while (!slice.isLastSlice()); return packageInfos; } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); } }
Ok, por lo que la lista que se está devolviendo se rellena desde ParceledListSlice.populateList()...
ParceledListSlice.populateList()
public T populateList(List<T> list, Creator<T> creator) { mParcel.setDataPosition(0); T item = null; for (int i = 0; i < mNumItems; i++) { item = creator.createFromParcel(mParcel); list.add(item); } mParcel.recycle(); mParcel = null; return item; }
Así que el elemento se está creando desde PackageInfo.CREATOR.createFromParcel()
…
Y finalmente el creator.createFromParcel
de PackageInfo
public static final Parcelable.Creator<PackageInfo> CREATOR = new Parcelable.Creator<PackageInfo>() { public PackageInfo createFromParcel(Parcel source) { return new PackageInfo(source); } public PackageInfo[] newArray(int size) { return new PackageInfo[size]; } };
Así que todo parece estar bien. Está creando un ParceledListSlice
del tipo PackageInfo
, por lo que en populateList
está creando un elemento PackageInfo
y lo pone en una List
de PackageInfo
, que es la lista devuelta. Todos los tipos / clases me parecen bien.
Así que mis preguntas,
- ¿Cómo ocurriría la anterior ClassCastException?
- ¿Por qué mostraría el tipo "en blanco" para el mensaje de error?
- ¿Y cuál sería una posible solución?
Yo estaba pensando en obtener la lista como una lista de Object
y comprobar " instanceof
", pero no creo que va a funcionar ya sea porque probablemente terminará diciendo
ClassCastException: no se puede convertir en java.lang.Object "o algo.
Cualquier idea y explicaciones sobre cómo esto podría suceder sería muy apreciada.
- ¿Está Dalvik / JVM simplemente estropeando?
- ¿Está dañada la memoria?
Yo sólo podía llegar a conjeturas salvajes =)
- ¿Cómo usar e importar eSpeak en eclipse?
- ¿Hay algo similar a strip_tags en Java?
- ¿Puede explicar alguien inflar método? Mayor comprensión de las vistas de Android
- Class Dimension para java en android
- Custom ViewPager para permitir que el control GoogleMap infantil se desplace horizontalmente
- ¿Cómo dibujar una vista encima de todo?
- El usuario no es elegible para esta compra en la versión de compra de aplicaciones3
- Los fragmentos de Android deben estar estáticos
Si está seguro de obtener ClassCastException
en esta línea exacta
for (PackageInfo pkgInfo : pkgList)
Cuando una razón está siguiendo – de alguna manera pkgList
contiene un valor de no PackageInfo
clase. Supongo que es NULL
valor. ¿Por qué no se puede ver en el mensaje de error ClassCast, porque className
para el objeto NULL es sólo una cadena vacía.
Ahora, cómo resolver este manual de uso para el bucle. for aech
bucle de for aech
utiliza for aech
debajo de la capilla, así que usted no tiene control sobre el lanzamiento de la clase en cada iteración. Pero si usas código como este:
for (int i = 0; i < pkgList.length; i++) { Object pkgInfoObj = pkgList.get(i); if (pkgInfoObj instanceof PackageInfo) { PackageInfo pkgInfo = (PackageInfo) pkgInfoObj; ApplicationInfo appInfo = pkgInfo.applicationInfo; // do some stuff, doesn't modify pkgInfo or appInfo or pkgList } }
Usted será capaz de controlar el casting de clase.
Además puede capturar ClassCastException
y simplemente omitir este paso de ciclo para el siguiente.
Esto parece ser un problema en el propio Android. He encontrado algunos informes de fallos contra Android que muestran comportamientos similares:
Problema 26644: ClassCastException y IncompatibleClassChangeError
Tema 36560: Excepción en (SensorManager.java:521)
También he visto el IncompatibleClassChangeError que se menciona en el problema 26644 también. Mi única suposición es que estas aparentemente imposibles excepciones / errores se deben a alguna extraña corrupción de memoria o dalvik / jvm problema. No parece que haya algo malo con el código en sí. Si alguien más tiene una mejor explicación, no dude en chip =)
- CrossWalk Webview no inicia la URL
- Error de la cámara "No se puede conectar a la cámara" o en algunos teléfonos aparece el error "La cámara está usando otra aplicación"