0 votos

Hola,

estoy haciendo una lista/detalle, las generé con eclipse y luego quise cambiarlas para que la lista se llene de datos de mi SQLite. Según entendí para esto lo mejor era usar CursorLoader, pero para usar el cursor loader necesitaba hacer un contentprovider, me dispuse a entender lo mejor posible todo esto, y según yo lo logré, estaba muy feliz, hice mi sqlhelper, hice mi contentprovider, puse mi cursorloader en el listfragment y…. no funcionó :(

No entiendo qué está fallando, el mensaje de error en el logcat (el principal, según me parece, porque después aparecen otros pero creo que son generados por el primero), dice “java.lang.IllegalArgumentException: column ‘_id’ does not exist”. Primero busqué a ver si por error había puesto _id en algún lado, y no lo encuentro en ninguna parte. Yo sé que para que funcione el content provider la tabla debe tener una columna _id INTEGER PRIMARY KEY AUTOINCREMENT, pero entiendo que no necesita llamarse de esa forma, y yo tengo mi ing_id que es ese tipo. Por si acaso cambié mi ing_id por _id y nada cambió. Entonces coloqué “banderas” en onCreateLoader de mi ListFragment, otras en OnCreate del ListFragment, y en el Query del contentprovider, antes del query y después del mismo justo antes del return, y todas estas banderas aparecen antes de dar el mensaje de error. No tengo idea de qué puede estar pasando después de esto, claro que entiendo que hay cosas que ocurren de forma concurrente, que no es programación lineal, pero el caso es que no sé como hacer para detectar donde está mi error.

Espero puedan ayudarme, mil gracias.

preguntado por Pilar Fernández Dic 22, 2014 en Android

1 Respuesta

0 votos
Mejor respuesta

Hola Pilar,

haces muy bien al utilizar ContentProvider con la base de datos. Es como se hace.

Sobre tu error, no has hecho nada mal, solo que no has creado un campo en la base de datos llamado “_id”. Es obligatorio que se llame así el id de la tabla de la base de datos cuando utilizas ContentProvider ;)

respondido por Jarroba [Admin] Dic 22, 2014

Hola, Ramón:

ya cambié mi tabla, le puse _id al campo INTEGER PRIMARY KEY AUTOINCREMENT, verifiqué que la tabla está creada correctamente y que se cargaron los datos de prueba, y sigue dando el mismo error. es la única tabla en mi base de datos, en verdad a mi me dan unos errores tan extraños que no hay quien los entienda :(

¿alguna otra razón que pueda generar este mensaje de error?,

muchas gracias,
Pilar

Por si sirve de algo, te envío el logcat completo:

47: I/ActivityThread(591): Pub com.example.quecocinare.contentproviders: com.example.quecocinare.IngredientesProvider
11-05 16:00:51.026: D/dalvikvm(591): GC_FOR_ALLOC freed 40K, 4% free 6907K/7171K, paused 186ms
11-05 16:00:51.187: I/dalvikvm-heap(591): Grow heap (frag case) to 13.055MB for 6515616-byte allocation
11-05 16:00:51.506: D/dalvikvm(591): GC_CONCURRENT freed 1K, 3% free 13269K/13575K, paused 20ms+21ms
11-05 16:00:54.097: D/gralloc_goldfish(591): Emulator without GPU emulation detected.
11-05 16:04:25.937: D/ListFragment On Create Loader(591): ingresando…
11-05 16:04:25.937: D/ListFragment On Create(591): luego del get Loader Manager
11-05 16:04:25.967: D/ListFragment On Create(591): luego de crear el cursor vacio
11-05 16:04:25.967: D/ListFragment On Create(591): a punto de salir
11-05 16:04:26.169: D/IngredientesProvider query(591): ingresando…
11-05 16:04:28.037: D/IngredientesProvider query(591): antes del query
11-05 16:04:28.047: D/IngredientesProvider query(591): despues del query
11-05 16:04:28.077: D/AndroidRuntime(591): Shutting down VM
11-05 16:04:28.077: W/dalvikvm(591): threadid=1: thread exiting with uncaught exception (group=0x409961f8)
11-05 16:04:28.180: E/AndroidRuntime(591): FATAL EXCEPTION: main
11-05 16:04:28.180: E/AndroidRuntime(591): java.lang.IllegalArgumentException: column ‘_id’ does not exist
11-05 16:04:28.180: E/AndroidRuntime(591): at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:301)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.database.CursorWrapper.getColumnIndexOrThrow(CursorWrapper.java:74)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.support.v4.widget.CursorAdapter.swapCursor(CursorAdapter.java:344)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.support.v4.widget.SimpleCursorAdapter.swapCursor(SimpleCursorAdapter.java:326)
11-05 16:04:28.180: E/AndroidRuntime(591): at com.example.quecocinare.ItemListFragment.onLoadFinished(ItemListFragment.java:125)
11-05 16:04:28.180: E/AndroidRuntime(591): at com.example.quecocinare.ItemListFragment.onLoadFinished(ItemListFragment.java:1)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:433)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:405)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.content.Loader.deliverResult(Loader.java:110)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.content.CursorLoader.deliverResult(CursorLoader.java:88)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.content.CursorLoader.deliverResult(CursorLoader.java:42)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:236)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:76)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.os.AsyncTask.finish(AsyncTask.java:602)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.os.AsyncTask.access$600(AsyncTask.java:156)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.os.Handler.dispatchMessage(Handler.java:99)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.os.Looper.loop(Looper.java:137)
11-05 16:04:28.180: E/AndroidRuntime(591): at android.app.ActivityThread.main(ActivityThread.java:4340)
11-05 16:04:28.180: E/AndroidRuntime(591): at java.lang.reflect.Method.invokeNative(Native Method)
11-05 16:04:28.180: E/AndroidRuntime(591): at java.lang.reflect.Method.invoke(Method.java:511)
11-05 16:04:28.180: E/AndroidRuntime(591): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
11-05 16:04:28.180: E/AndroidRuntime(591): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
11-05 16:04:28.180: E/AndroidRuntime(591): at dalvik.system.NativeStart.main(Native Method)
11-05 16:04:30.737: I/Process(591): Sending signal. PID: 591 SIG: 9

Cuando haces el SELECT de la consulta, ¿Estás devolviendo el “_id” (por ejemplo “SELECT _id FROM miTabla”)? Es obligatorio que se devuelva ésta columna.

ok, entonces es eso, porque no lo estoy devolviendo ;)

mil gacias, es difícil encontrar tantas reglas, lo de la columna _id obligatoria lo sabía, pero había entendido que no debía llamarse así, lo de retornar de forma obligatoria el _id no lo sabía

De nada Pilar.

Si quieres llamar como quieras al ID de la tabla de la base de datos puedes utilizar un alias para que se siga llamando “_id” (por ejemplo “SELECT miIdentificador AS _id FROM miTabla”).

Hola, Ramón:

aún estoy con este problema. Le he dado mil vueltas, lo he vuelto a programar ordenando las cosas de otra forma (ha quedado más organizado) pero me he encontrado con un problema a la hora de compilar que no tenía antes y no sé que cambie para que me de este problema. Es cuando estoy haciendo el CursorLoader en el Fragment, he visto muchos ejemplos en internet y siempre cuando definen el onCreateLoader lo hacen como:

public Loader<Cursor> onCreateLoader(int id, Bundle args)

y a la hora de retornar un valor retornan un CursorLoader, en mi caso:

CursorLoader MiCursor = new CursorLoader(getActivity(), baseUri, null, null, null, null);
return MiCursor;

le estoy enviando el select en null porque entiendo que así retorna todas las columnas, lo que incluye al _id. Según entiendo esto es como hacer un Select * from Ingredientes; el select más simple.

El problema es que se empeña en decir que no puedo convertir un CursorLoader en Loader<Cursor>, y no he encontrado en internet ua explicación aesto porque en todos los ejemplos está igual, ¿qué puedo estar haciendo mal?, ¿me faltará importar algo? (esto se me acaba de ocurrir, voy a revizarlos)

saludos,
Pilar

Ah, me faltó una duda. Estoy usando para inicializar el Loader:

getLoaderManager().initLoader(0, null, this);

pero en un ejemplo vi otro init diferente:

getSupportLoaderManager().initLoader(1, null, this);

y no llegué a entender la diferencia entre ambos.

ok, olvida el problema de casting, efectivamente era un tema de importación, estaba mezclando librerías incompatibles :(

a veces cuando estoy escribiendo la pregunta la respuesta se me viene a la cabeza jeje

Suele pasar que cuando estás pensando en otra cosa que no está centrado en el problema -como escribir un post- llega la solución por sí sola :)

Fíjate que siempre que venga en algún método o clase la palabra “Support”, nos está diciendo que dichas clases que están preparadas para versiones de Android antiguas, que están en Beta o que ya no tienen soporte.

Por norma recomiendo no utilizar dichas bibliotecas, salvo que no haya otra opción (por ejemplo, requerimos versiones muy antiguas de Android, o de cosas que están en beta que pueden ser interesante utilizar).

Y sobre todo no mezclar nunca librerías “Support” con las estables, sino dará esta clase de problemas.