Algunas preguntas sobre los cursores de la base de datos SQLite en Android

Para implementar el acceso a la base de datos en mi aplicación he seguido Lars Vogel tutorial , pero estoy muy confundido acerca de un par de cosas …

1) Cada vez que se hace una llamada a fetchTodo , se creará y devolverá un nuevo cursor. Dejar el cursor anterior para el recolector de basura. Por lo tanto, si no utilizo startManagingCursor o incluso el CursorLoader para ese asunto, debo llamar a un .close() en el cursor cuando haya terminado con él? Fuera del ámbito de fetchTodo por supuesto, ejemplo:

 Cursor cursor = mNotesAdapter.fetchTodo(); // do something... cursor.close(); 

He terminado con este cursor y se creará uno nuevo en la próxima búsqueda, ¿debo cerrarlo así o debo dejarlo para el recolector de basura? Aunque creo que estoy hablando de 2 cosas totalmente diferentes … Punto de ser, ¿Debo cerrarlo como en el ejemplo anterior o no?

2) Cursor también tiene un método .deactivate() y la documentación dice que utiliza menos recursos (que los cursores activos). ¿Cuándo debo usar esto exactamente? Por ejemplo, en mi aplicación, tengo una ListActivity que se rellena a través de un SimpleCursorAdapter (la inicialización de código para esto sólo se llama una vez). El cursor que se utiliza es una variable de miembro de clase, porque lo necesito fuera del método que rellena la lista. Lo necesito para volver a consultar la base de datos cuando algo se elimina de ella. Pero hasta que se elimine un registro, que es una acción del usuario y puede tardar un tiempo en pasar, ¿debo desactivar el cursor mientras tanto? Porque volverá a estar activo cuando vuelva a llamar .requery() . ¿O el SimpleCursorAdapter va a dejar de funcionar porque el cursor no está activo?

EDIT: Acabo de probar este y descubrí que no puedo llamar a deactivate() después de configurar el adaptador de cursor. La lista estará vacía si el cursor no está activo, por lo que debe permanecer activo durante el tiempo que se muestre ListActivity. Al final, debemos dejar que StartManagingCursor maneje entonces. O el nuevo CursorLoader .

3) Sé que startManagingCursor / stopManagingCursor está obsoleto, pero no estoy apuntando a Honeycomb (al menos por el momento) y no quiero tratar con el nuevo CursorLoader por ahora. Pero en el tutorial anterior, startManagingCursor se utiliza en todas partes, pero stopManagingCursor nunca se llama una vez. Por qué no? ¿Android trata con eso en su propia manera? Cualquier situación que debería llamar a stopManagingCursor ?

Editar: Respuesta actualizada para reflejar la pregunta actualizada 1:

1) Cada vez que se hace una llamada a fetchTodo, se creará y devolverá un nuevo cursor. Dejar el cursor anterior para el recolector de basura. Por lo tanto, si no utilizo startManagingCursor o incluso el CursorLoader para ese asunto, debo llamar a un .close () en el cursor cuando haya terminado con él?

Sí, definitivamente deberías decirle a Android que startManagingCursor() , usa LoaderManager / CursorLoader o close() tú mismo. No hacerlo perderá memoria, el GC no ayudará con eso, ya que hay recursos nativos detrás del Cursor (por ejemplo, manejadores de archivos a la base de datos).

2) Cursor también tiene un método .deactive () y la documentación dice que utiliza menos recursos (que cursores activos). ¿Cuándo debo usar esto exactamente? …

EDIT a otros lectores: El OP encontró una respuesta y la publicó en su pregunta. Lo siguiente sigue siendo válido:

Nunca he utilizado deactivate() (no hay deactive() ), tal vez alguien más puede explicar esto. Si desea realizar consultas / actualizaciones realmente sin dolor, consulte el marco de LoaderManager : no es sólo para Honeycomb: con la biblioteca compat puede usar LoaderManager (y Fragments ) en Android 1.6. No sólo es menos código para que usted pueda escribir, sino que descarga completamente estas cosas a Android, mucho más que startManagingCursor() .

EDIT2: Algunas notas sobre LoaderManager

Hay tutoriales de LoaderManager en developer.android.com pero estos son bastante … complejos y difíciles de entender la primera vez como la mayoría de los tutoriales allí. También tuve que cavar mucho, la mejor parada todo en uno que he encontrado hasta ahora es http://mobile.tutsplus.com/tutorials/android/android-sdk_loading-data_cursorloader/ (además de todos los javadocs y compat lib source Puede encontrar) — la forma en que LoaderManager funciona es muy similar a los cuadros de diálogo gestionados (ahora también obsoletos, reemplazados por DialogFragment ) con sus métodos onCreateDialog , onPrepareDialog donde simplemente dices a Android que muestre el diálogo # 123 y luego Android llama a tu Código con ese ID; Mismo para cargadores: "load loader # 123", Android llama a onCreateLoader() .

El único inconveniente obvio es, inicialmente, que LoaderManager basa en gran medida en el marco ContentProvider y algunas personas parecen realmente no les gusta eso. Claro, se trata de aprendizaje adicional y código, pero una vez que tiene un ContentProvider para sus propios datos (incluso si sólo se utiliza de forma privada en su aplicación), todos los data-to-view bindng es una brisa con CursorLoader . IMHO, hay poca diferencia entre rodar su propio "proveedor de contenido" y en realidad la aplicación de ContentProvider – pero esto es sólo mi muy controversial opinión 🙂

3) Sé que startManagingCursor / stopManagingCursor está obsoleto, pero no estoy apuntando a Honeycomb (al menos por el momento) y no quiero tratar con el nuevo CursorLoader por ahora. Pero en el tutorial anterior, startManagingCursor se utiliza en todas partes, pero stopManagingCursor nunca se llama una vez. Por qué no? ¿Android trata con eso en su propia manera? Cualquier situación que debería llamar a stopManagingCursor?

Una vez que usted llama a startManagingCursor() el Cursor ya no es su problema. Android se encargará de cerrar el Cursor cuando tu Activity sea ​​destruida (el usuario se aleja, el cambio de orientación, …). No hay necesidad de igualar una llamada a startManagingCursor() con una llamada a stopManagingCursor() – normalmente no desea asumir la carga de administrar un Cursor nuevo una vez que se haya librado de él.

  • Actualizar la base de datos SQLite de una versión a otra?
  • Consulta de cursor no sensible a mayúsculas y minúsculas con operador LIKE (que funciona para todos los entornos locales)
  • ¿Cuál es el modo de subprocesamiento predeterminado de SQLite en Android?
  • ¿Cómo puedo ordenar mi base de datos SQLITE en orden descendente, para una aplicación de Android?
  • implementar el marco de sincronización de Microsoft con el dispositivo Android
  • Problema sobre sqlite base de datos, no tal tabla:
  • ¿Cómo sincronizar los datos del servidor en la aplicación android?
  • Intente volver a abrir un objeto ya cerrado: SQLiteDatabase:
  • Android SqliteAssetHelper - fusionar las tablas de la base de datos del activo con el existente
  • SQLiteException no se captura
  • getApplicationContext () devuelve null, pero funciona en otras actividades
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.