• Non ci sono risultati.

Content provider

3.3 Definizione database locale e database remoto Esercizi2013

4.1.1 Content provider

Figura 4.1: Diagramma di sequenza che illustra l’interazione fra Content Provider e Cursor Loader

Utilizzo del Content Provider all’interno dell’Applicazione Nel dia- gramma di sequenza in figura 4.1 viene mostrato in modo semplificato il fun- zionamento e l’interazione dei componenti quando viene utilizzato un Content Provider per la gestione dei dati e un loader per il loro caricamento.

I particolari pi`u importanti da evidenziare sono:

• Il caricamento dei dati `e gestito dal loader, un thread separato che quindi non inficia il funzionamento dell’interfaccia grafica e del resto dell’applicazione.

• In caso di distruzione e ricreazione del fragment e della view, i dati rimangono salvati all’interno del cursore del loader, e vengono suc- cessivamente richiamati senza dover eseguire una seconda query sul database.

• L’adapter viene inizialmente creato senza una fonte dati, nel momento in cui gli verr`a assegnato un cursore eseguir`a il caricamento dei dati sulla ListView.

4.1 Descrizione dell’implementazione dell’applicazione 77

• Il sistema gestisce in automatico un observer sui dati, al verificarsi del loro cambiamento sul database viene dato segnale al loader di ripetere il caricamento dei dati e di conseguenza l’aggiornamento della listview.

Implementazione Per implementare il Content Provider relativo ai dati del database locale, si `e creata una classe figlia della classe di sistema Content Provider.

Al suo interno devono essere presenti i seguenti elementi:

La fonte dei dati In questo caso viene istanziato un oggetto database di tipo SQLiteDatabase, dichiarato private e con pattern Singleton.

Authority del provider Identifica univocamente il provider.

1 private static final String AUTHORITY =”it.unibo.tesi.programmazione.main.contentProvider”;

Paths delle tabelle Sono costanti utilizzate all’interno del Content Provider, sono create utilizzando i dati delle classi che descrivono le tabelle.

1 private static final String TAB NEWS PATH = DBTGnews.TABLE NAME;

Uri delle tabelle Vengono definiti gli URI di ogni tabella tramite com- posizione di elementi definiti precedentemente insieme a stringhe standard specifiche della sintassi degli URI (content:// ).

Metodo statico per ottenere l’Uri della tabella partendo dal suo nome

UriMatcher Metodo che si occupa di controllare se un Uri `e gestito o meno da questo Content Provider.

ID univoci per ogni Uri Ad ogni Uri `e associato un codice univoco che a sua volta viene dichiarato staticamente nella classe.

Aggiunta dei parametri del Content Provider all’UriMatcher Vengono aggiunti gli elementi precedentemente creati, authority, path e codice univoco all’UriMatcher che in questo modo potr`a riconoscerli.

Definizione del tipo di dato esposto dal Content Provider Il tipo dovr`a essere nella forma tipo/sottotipo ad esempio “image/jpg”. In questo caso vengono restituiti dei cursori a tabelle.

Metodo per convertire il codice restituito dall’UriMatcher nel relativo tipo di dato fornito

Override del costruttore della classe In fase di creazione del Con- tent Provider si ottiene un’istanza del database tramite il relativo helper.

Definizione delle operazioni C.R.U.D. Il Content Provider fornisce una interfaccia delle operazioni C.R.U.D. standard, al suo interno `e quindi necessario definire quali operazioni verranno effettivamente eseguite. Questo dipende da come sono memorizzati i dati nel layer sottostante al Content Provider. In questo caso abbiamo un database e le relative operazioni SQL standard.

Versione dei Dati Un dettaglio specifico del dominio applicativo in esame `e il concetto di versione dei dati.: `e infatti necessario fornire al servizio remoto la versione attuale dei dati presenti nell’applicazione per ottenere in risposta solo le modifiche effettuate successivamente a quella specifica versione. Per la gestione di questo dato `e stata implementata una soluzione non ottimale per massimizzare la compatibilit`a dell’applicazione con il maggior numero di versioni del sitema operativo, si vuole quindi illustrare ci`o che `e stato implementato e quale sarebbe la soluzione migliore al problema.

Soluzione ottimale Il concetto di versione dei dati `e una informazio- ne prettamente inerente ai dati stessi, sarebbe quindi corretto che la sua

4.1 Descrizione dell’implementazione dell’applicazione 79

gestione fosse demandata al Content Provider, come per tutto il resto delle operazioni. Per ottenere questo risultato, `e possibile aggiungere dei metodi personalizzati all’interno del Content Provider. Dal momento che l’applica- zione non accede mai, direttamente, al Content Provider ma utilizza sempre un Content Resolver e un Uri per farlo, dalle API 11 di Android `e stata implementata una nuova funzione:

1 public final Bundle call (Uri uri , String method, String arg, Bundle extras)

Il suo scopo `e appunto far eseguire un metodo aggiuntivo al Content Provider indirizzato dall’Uri dato input. Nel metodo richiamato verr`a poi gestito il salvataggio del dato o all’interno di una tabella apposita o tramite altre metodi di salvataggio forniti dal sistema o il recupero di un valore precedentemente salvato, quando richiesto.

Il motivo per cui si `e deciso di non realizzare questa soluzione `e la volont`a di mantenere il livello di API minimo a 9, ovvero alla versione di Android 2.3.3. in quanto ancora largamente diffusa. (vedi: 1.2.3)

Soluzione implementata Per ovviare alla problematica si `e scelto di distaccare l’informazione sulla versione dei dati dagli stessi dati. Durante le operazioni di aggiornamento del database, il valore fornito dal server viene salvato nei dati privati dell’applicazione tramite l’utilizzo delle SharedPrefe- rences (vedi: 3.2.5) e e richiamato dalle stesse per poter fornire il parametro alla richiesta HTTP-POST da effettuare verso il server remoto.

Tramite opportuna implementazione del gestore delle SharedPreferences si `e fatto in modo che il dato non venga mai cancellato, quindi l’unico modo di perderne il valore `e disinstallare l’applicazione, ma in tal caso verrebbe anche eliminato il database facendo perdere dunque al dato ogni significato. Con questa soluzione si garantisce quindi che il dato sia sempre disponibile e abbia un ciclo di vita identico a quello del database, seppur demandando la gestione dei dati a due diversi moduli del sistema.

Documenti correlati