2010-08-30 17 views
5

Ho una domanda di progettazione Android generale sull'accesso ai dati. Ho una serie di attività nella mia applicazione che devono accedere a un database SQLite. Al fine di racchiudere tutta la logica di accesso ai dati in un unico punto, ho creato una classe DatbaseHandler che si occupa di tutta la logica di accesso ai dati. Questa classe si occupa di creare clausole dove, chiamando il database e interrogando il cursore risultante per recuperare i risultati della query e restituirli al chiamante. Lo scopo di questa classe è quello di racchiudere tutto il codice di accesso ai dati in un unico posto in modo che possa essere facilmente gestito e gestito rispetto alla logica di accesso ai dati diffusa in tutte le attività. Ogni attività che ha bisogno di accedere al database crea un'istanza di questa classe DatabaseHandler e passa ad essa un riferimento di android.content.Context. La classe DatabaseHandler utilizza quindi questo oggetto Context per chiamare un provider di contenuto sottostante come segue context_i.getContentResolver(). Query (...).Approccio alla progettazione dell'accesso al database Android

La logica di accesso ai dati personali (la logica di gestione del cursore è specifica) non è nell'attività e quindi non riesco a gestire il ciclo di vita dei cursori, pertanto è probabile che vi siano perdite di memoria.

Le mie domande sono le seguenti -

  1. Come posso (se ancora possibile) la gestione del ciclo di vita dei cursori al di fuori di un'attività?
  2. Ogni attività dovrebbe anche creare un'istanza di questa classe di gestore dati e passarvi un'istanza di Context? Forse il mio approccio progettuale è sbagliato e dovrei esporre queste funzioni di accesso ai dati come metodi statici che prendono come parametro un'istanza dell'attività di chiamata. In questo modo potrei eseguire query gestite e lasciare che l'attività si occupi di gestire il ciclo di vita dei cursori?

Mi piacerebbe davvero capire l'approccio migliore. Qualche consiglio sarebbe molto apprezzato

risposta

2

L'approccio standard:
Normalmente, se si dispone di un ContentProvider scritto da te stesso e ti sei registrato correttamente nel file manifest.xml, si può solo fare (per esempio)

@Override 
public void onCreate(Bundle savedInstanceState){ 
    ... 

    if (getIntent().getData() == null) { 
     getIntent().setData(MyMetaData.CONTENT_URI); 
    } 

    Cursor cursor = managedQuery(getIntent().getData(), null, null, null, null); 

    //create an appropriate adapter and bind it to the UI 
    ... 
} 

questo chiamerà automaticamente il ContentProvider che è in grado di gestire il contenuto dato uri, dato che avete registrato nel file manifest.xml come

<provider android:name="MyContentProvider" android:authorities="com.mycompany.contentprovider.MyContentProvider" /> 

Suggerisco sempre alle persone di dare un'occhiata allo Notepad example per sapere come implementare ContentProvider.

Alternative:
In generale, se avete bisogno di accedere ai dati solo all'interno delle vostre attività Vorrei aderire al "metodo standard" utilizzando ContentProviders, che btw. probabilmente lo rende la soluzione più flessibile.
Se la soluzione necessita di per accedere ai dati anche da classi non attive in cui non si dispone dei metodi "managedQuery", è possibile implementare una sorta di classi DAO (Data Access Object). Un esempio potrebbe essere

public class MyDataDao implements IMyDataDao { 
    private ContentResolver contentResolver; 

    public MyDataDao(ContentResolver contentResolver){ 
     this.contentResolver = contentResolver; 
    } 


    @Override 
    public MyDataObject readMyDataObjectById(long id){ 
     MyDataObject result = null; 

     Cursor myDataObjectCursor = contentResolver.query(...); 
     if(myDataObjectCursor != null && myDataObjectCursor.moveToFirst()){ 
     result = new MyDataObject(); 
     result.setTitle(myDataObjectCursor.get..); 
     ... 
     } 
     myDataObjectCursor.close(); 

     return result; 
    } 
} 

Potrebbe funzionare anche.È quindi chiama il tuo DAO

IMyDataDao dao = new MyDataDao(context.getContentResolver()); 
MyDataObject anObj = dao.readMyDataObjectById(10); 
... 

speranza che si ha nella direzione giusta :)

+0

Grazie per la risposta Juri ma penso che avete forse letto male le domande. Ho già un fornitore di contenuti e un oggetto di accesso ai dati sul posto. (Ho modificato leggermente le domande dall'alto per renderle un po 'più chiare). 1. Come posso, se possibile, gestire il ciclo di vita dei cursori dall'esterno di un'attività (all'interno dell'oggetto di accesso ai dati)? 2. Ogni attività dovrebbe creare un'istanza di questo oggetto di accesso ai dati e passare un'istanza di Context ad esso? Forse il DAO dovrebbe esporre i metodi statici in modo che ogni attività non debba creare un'istanza dell'oggetto di accesso ai dati? – Brian

+0

Ho già fornito un esempio per gestire il cursore all'esterno dell'attività, ad esempio nell'oggetto DAO. Ovviamente dovresti prendere in considerazione la creazione di istanze singleton dei tuoi oggetti dao, quelle statiche sono di solito cattive per le unit test se ti interessa. – Juri

Problemi correlati