9

Here indica che il costruttore di livello 1 dell'API SimpleCursorAdapter è obsoleto e si consiglia l'uso di LoaderManager e CursorLoader.Il vecchio costruttore di SimpleCursorAdapter è deprecato .. davvero?

Ma approfondendo le LoaderManager e CursorLoader 's usano ho trovato this esempio in cui all'interno di una classe interna che si estende un ListFragment (un'estensione del frammento stesso suppongo) creiamo un CursorLoader. Tutto sembra ok, tranne per il fatto che CursorLoader prende un argomento come Uri. Quindi questo implica che ho bisogno di creare un ContentProvider per ottenere l'accesso al mio database.

Devo confessare che sembra un overkill dover passare tutto questo solo per creare un semplice ListView con elementi provenienti da un database. Specialmente se non intendo rendere disponibili i miei dati di database ad altre app e lo scopo principale di un fornitore di contenuti è quello di farlo.

Quindi ne vale davvero la pena?

Soprattutto in casi come il mio in cui è probabile che il contenuto da prelevare sia piccolo. Sto seriamente pensando di farlo alla vecchia maniera, cosa dici?

+1

Stai sostenendo API 11 o superiori? – Cristian

+0

No, certo che non lo sono, ero disposto a utilizzare la libreria di compatibilità che fornisce il supporto delle versioni precedenti per Fragments and Loaders. – Bilthon

+0

qual è il nome dell'esempio che hai trovato (sembra qualcosa che voglio fare nella mia app)? Il collegamento sta solo spiegando i campioni in generale .. – Karl

risposta

8

ho scritto un simple CursorLoader che non ha bisogno di un fornitore di contenuti:

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; 
    } 
} 

Ha bisogno solo la classe AsyncTaskLoader. O quello di Android 3.0 o versione successiva o quella fornita con il pacchetto di compatibilità.

+0

grazie mille @Cristian – confucius

+0

Trovato un buon esempio di codice per SimpleCursorLoader - https://bitbucket.org/ssutee/418496_mobileapp/src/fc5ee705a2fd/demo/DotDotListDB/src/th/ac/ku/android/sutee/dotdotlist - found è molto utile! – Shushu

4

Basta usare il costruttore sottostante, quello che prende le bandiere. Non utilizzare FLAG_AUTO_REQUERY, basta passare 0 per i flag.

A meno che non sia davvero necessario gestire le modifiche dei dati al DB sottostante mentre l'utente guarda il ListView, non è necessario preoccuparsi della necessità di eseguire la query.

Se invece si desidera che ListView mostri le modifiche al DB mentre l'utente sta guardando l'elenco, seguire i consigli di Google e utilizzare CursorLoader.

EDIT:

Dal momento che il secondo costruttore è disponibile solo in API 11 si può solo voler estendere CursorAdapter te stesso. Devi praticamente solo implementare bindView e newView e il gioco è fatto.

1

Utilizzare solo il costruttore deprecato simpleCursorAdapter. Questo tipo di errore è apparso quando stavo sviluppando la mia app ma l'ho usata e ha funzionato perfettamente con la mia app. Oppure prova ad usare il costruttore qui sotto deprecato nel sito web degli sviluppatori Android che ha un argomento in più sull'argomento flag con esso.

+0

Ma si noti che il secondo costruttore è stato introdotto solo in api livello 11. Quindi dovrei aggiungere la libreria di compatibilità solo per usarlo. Aggiungere una libreria statica rende anche il mio apk più grande alla fine, e se è solo per il gusto di usare quel costruttore, sinceramente non ne vedo il senso. – Bilthon

1

Credo che CursorLoader sia attualmente destinato all'uso con ContentProvider.

Se si desidera caricare direttamente dal database utilizzando il nuovo framework; puoi prendere in considerazione l'estensione di AsyncTaskLoader e il suo ritorno da onCreateLoader invece di usare CursorLoader.

Se si utilizzano i metodi esistenti, è necessario prestare maggiore attenzione alla durata dell'operazione di query. Se la tua query impiegherà una quantità notevole di tempo, prendi in considerazione l'utilizzo di un AsyncTask per caricare il cursore (e sii consapevole della esecuzione della query nel thread dell'interfaccia utente).

0

So che questa discussione è obsoleta, ma è sufficiente aggiungere un ultimo parametro alla creazione dell'oggetto SimpleCursorAdapter. Basta aggiungere ", 0".

È una bandiera che piace a Android e l'avviso scompare.

Esempio:

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