9

Here dice que SimpleCursorAdapter 's API nivel 1 constructor está en desuso y se recomienda el uso de LoaderManager y CursorLoader.El viejo constructor de SimpleCursorAdapter se depreció ... ¿en serio?

Pero ahondando en las LoaderManager y CursorLoader 's utilizan encontré this ejemplo en el interior de una clase interna que se extiende un ListFragment (una extensión de sí mismo Fragmento supongo) creamos un CursorLoader. Todo parece estar bien, excepto por el hecho de que CursorLoader toma un Uri como argumento. Entonces esto implica que necesito crear un ContentProvider para acceder a mi base de datos.

Debo confesar que parece una exageración tener que pasar por todo esto para crear un simple ListView con elementos procedentes de una base de datos. Especialmente si no tengo la intención de hacer que mis datos de base de datos estén disponibles para otras aplicaciones, y el propósito principal de un proveedor de contenido es hacer eso.

¿Realmente vale la pena?

Especialmente en casos como el mío, donde es probable que el contenido que se va a buscar sea pequeño. Estoy considerando seriamente hacerlo a la vieja usanza, ¿qué dices?

+1

los apoyamos API 11 o superior solamente? – Cristian

+0

No, por supuesto que no, estaba dispuesto a utilizar la biblioteca de compatibilidad que brinda compatibilidad con versiones anteriores para Fragmentos y cargadores. – Bilthon

+0

¿Cuál es el nombre de la muestra que encontraste (parece algo que quiero hacer en mi aplicación)? El enlace solo explica las muestras en general ... – Karl

Respuesta

8

me escribió una simple CursorLoader que no necesita un proveedor de contenido:

import android.content.Context; 
import android.database.Cursor; 
import android.support.v4.content.AsyncTaskLoader; 

/** 
* Used to write apps that run on platforms prior to Android 3.0. When running 
* on Android 3.0 or above, this implementation is still used; it does not try 
* to switch to the framework's implementation. See the framework SDK 
* documentation for a class overview. 
* 
* This was based on the CursorLoader class 
*/ 
public abstract class SimpleCursorLoader extends AsyncTaskLoader<Cursor> { 
    private Cursor mCursor; 

    public SimpleCursorLoader(Context context) { 
     super(context); 
    } 

    /* Runs on a worker thread */ 
    @Override 
    public abstract Cursor loadInBackground(); 

    /* Runs on the UI thread */ 
    @Override 
    public void deliverResult(Cursor cursor) { 
     if (isReset()) { 
      // An async query came in while the loader is stopped 
      if (cursor != null) { 
       cursor.close(); 
      } 
      return; 
     } 
     Cursor oldCursor = mCursor; 
     mCursor = cursor; 

     if (isStarted()) { 
      super.deliverResult(cursor); 
     } 

     if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) { 
      oldCursor.close(); 
     } 
    } 

    /** 
    * Starts an asynchronous load of the contacts list data. When the result is ready the callbacks 
    * will be called on the UI thread. If a previous load has been completed and is still valid 
    * the result may be passed to the callbacks immediately. 
    * <p/> 
    * Must be called from the UI thread 
    */ 
    @Override 
    protected void onStartLoading() { 
     if (mCursor != null) { 
      deliverResult(mCursor); 
     } 
     if (takeContentChanged() || mCursor == null) { 
      forceLoad(); 
     } 
    } 

    /** 
    * Must be called from the UI thread 
    */ 
    @Override 
    protected void onStopLoading() { 
     // Attempt to cancel the current load task if possible. 
     cancelLoad(); 
    } 

    @Override 
    public void onCanceled(Cursor cursor) { 
     if (cursor != null && !cursor.isClosed()) { 
      cursor.close(); 
     } 
    } 

    @Override 
    protected void onReset() { 
     super.onReset(); 

     // Ensure the loader is stopped 
     onStopLoading(); 

     if (mCursor != null && !mCursor.isClosed()) { 
      mCursor.close(); 
     } 
     mCursor = null; 
    } 
} 

Sólo se necesita la clase AsyncTaskLoader. O el de Android 3.0 o superior, o el que viene con el paquete de compatibilidad.

+0

muchas gracias @Cristian – confucius

+0

Encontré una buena muestra de código para SimpleCursorLoader - https://bitbucket.org/ssutee/418496_mobileapp/src/fc5ee705a2fd/demo/DotDotListDB/src/th/ac/ku/android/sutee/dotdotlist - found ¡es muy útil! – Shushu

4

Simplemente use el constructor debajo de él, el que toma las banderas. No use el FLAG_AUTO_REQUERY, simplemente pase 0 para las banderas.

A menos que realmente necesite manejar los cambios de datos en el DB subyacente mientras el usuario está mirando el ListView, entonces no necesita preocuparse por la necesidad de volver a consultar.

Si, por otro lado, desea que el ListView muestre los cambios en el DB mientras el usuario está mirando la lista, siga los consejos de Google y use el CursorLoader.

EDIT:

Desde el segundo constructor sólo está disponible en 11 API puede que sólo quieren extender CursorAdapter mismo. Basta con implementar bindView y newView y listo.

1

Utilice simpleCursorAdapter constructor en desuso solo. Este tipo de error apareció cuando estaba desarrollando mi aplicación pero la usé y funcionó a la perfección con mi aplicación. O intente usar el constructor debajo del obsoleto en el sitio web de desarrolladores de Android, que tiene un argumento adicional, es decir, el argumento de la bandera con él.

+0

Pero observe que el segundo constructor solo se introdujo en el nivel 11 de la API. Por lo tanto, tendría que agregar la biblioteca de compatibilidad solo para usarlo. Agregar una biblioteca estática también hace que mi apk sea más grande al final, y si es solo por el uso de ese constructor, honestamente no veo el sentido. – Bilthon

1

Creo que CursorLoader está diseñado actualmente para ser utilizado con ContentProvider.

Si desea cargar directamente desde su base de datos utilizando el nuevo marco; puede considerar extender AsyncTaskLoader y devolverlo desde onCreateLoader en lugar de usar un CursorLoader.

Si está utilizando los métodos existentes, tiene que tener más cuidado de cuánto tiempo llevará su operación de consulta. Si su consulta llevará cantidades de tiempo considerables, considere usar AsyncTask para cargar el cursor (y tenga en cuenta que se está ejecutando una nueva consulta en el hilo de la interfaz de usuario).

0

Sé que este hilo es viejo, pero podría agregar un último parámetro en la creación del objeto SimpleCursorAdapter. Solo agregue ", 0".

Es una bandera que le gusta a Android y la advertencia desaparece.

Ejemplo:

SimpleCursorAdapter dataAdapter = new SimpleCursorAdapter(getApplicationContext(), R.layout.item_list_layout, cursor, fromDB(), toLayout(), 0); 
Cuestiones relacionadas