2011-08-19 1 views
5

Ho una semplice applicazione Android che utilizza un'istanza di una classe, chiamiamola DataManager, per gestire l'accesso alle classi di dominio in modo simile a Façade. Inizialmente l'ho progettato come un singleton che poteva essere recuperato usando metodi statici, ma alla fine mi sono irritato con la confusione della mia implementazione e rifatto a ciò che pensavo fosse un'idea più semplice e pulita.È possibile, e qual è la strategia migliore, passare oggetti per riferimento da un'attività alla successiva?

Ora l'idea è che per ogni file che viene aperto, viene creato uno DataManager, che gestiscono l'I/O del file e la modifica delle classi di dominio (ad esempio Book). Quando avvii una nuova attività, passo questa istanza come Serializable in più (non ho ancora iniziato a usare Parcelable ancora, ma mi aspetto che lo farò quando avrò il concetto di base funzionante), e poi prendo lo Intent in il metodo onCreate() della nuova attività.

Tuttavia, il confronto degli oggetti indica che l'oggetto inviato da un'attività non è identico (riferimenti diversi) all'oggetto recuperato da Bundle nella seconda attività. La lettura su Bundle (su StackOverflow, ecc.) Suggerisce che i pacchetti non possono fare altro che il pass-by-value.

Quindi qual è la strategia più pulita e sicura per il passaggio di un oggetto tra le attività? Come la vedo io potevo

  1. Dimenticate il passaggio per riferimento e vivere con ogni Activity con il proprio oggetto DataManager. Passa il nuovo DataManager ogni volta che chiudo un'attività in modo che l'attività sottostante possa utilizzarla. (La soluzione semplice, penso.)

  2. Torna a utilizzare un singleton DataManager e utilizzare un metodo statico per ottenerlo da ogni Activity. (Non appassionato di utilizzare nuovamente i singleton).

  3. Estendere l'applicazione per creare una sorta di riferimento globale a DataManager. (Ancora una volta, non appassionato all'idea di globals.)

È un buon riassunto? C'è qualche altra strategia salutare che potrei usare?

+3

Solo una parola sulla terminologia: Java * sempre * utilizza il pass-by-value, indipendentemente dal fatto che si passino riferimenti o tipi primitivi. Gli oggetti non sono mai passati affatto. Penso di sapere cosa intendi, ma usare il pass-by-reference è un po 'una distrazione. –

+1

Preferirei utilizzare il metodo Singleton, è classicamente utilizzato per le classi a istanza singola con un punto di accesso globale. – Egor

+1

Se è necessario utilizzare un Singleton, è possibile utilizzare una sottoclasse dell'applicazione. Nella mia esperienza, è meglio evitare le lezioni DAO su Android e utilizzare ContentProviders. Sono intrinsecamente disponibili ovunque. –

risposta

4

Un altro approccio potrebbe essere quello di creare un servizio. La prima attività avvia il servizio e si lega a esso, quando si avvia un nuovo intent, si separa la prima attività e quando si avvia la seconda attività, eseguire il binding al servizio.

In questo modo non è necessario interrompere il servizio o preoccuparsi di trasferire dati tra le attività.

+0

questo è il miglior modo Android per fare le cose .. Rispetta le strategie/il concetto di gestione della memoria di Android –

0

Java non ha passato per riferimento in modo che l'opzione è fuori, vorrei suggerire l'iniezione di dipendenza per il trasferimento di dati tra le attività. Altrimenti sicuramente il singleton sarebbe la strada da percorrere.

+0

Che tipo di iniezione di dipendenza stai suggerendo? Ad essere onesti non mi ero reso conto che fosse un'opzione su Android. È un'opzione semplice? – Spinner

0

quello prescritto Sta andando implementando Parcellable interfaccia, questo è il modo per passare oggetti tra le attività .. e il 2 ° e migliore scelta è quella di fare un Singleton per essere sicuri che il suo unico oggetto.

+0

L'uso di Parcelable anziché Serializable significa che l'oggetto viene passato in giro, eliminando la necessità di passarlo all'attività precedente dopo averlo utilizzato? – Spinner

0

Crea il tuo DataManager come Singleton che implementa Service. Collega il servizio alla tua applicazione nel file manifest xml (vedi il link), e avrai un singleton persistente a cui le tue attività possono accedere senza problemi.

Passare argomenti discutibili può diventare molto complicato se è necessario ottenere molti dati. L'approccio singleton, sebbene solitamente considerato un anti-pattern, funziona come un incantesimo in casi come questi. Ricorda solo di non creare più singleton che interagiscono tra loro.

0

Suggerirei di utilizzare una sottoclasse dell'applicazione. Ti consente di mantenere un singolo riferimento alla classe DataManger ed è persistente finché dura la tua app.

Un singleton con un campo statico funziona anche, ma nella documentazione c'è qualche posto in cui si dice che il contenuto dei campi statici non è un posto sicuro in cui archiviare i dati. Come ho capito, i campi statici dovrebbero persistere finché il tuo ClassLoader rimane in memoria. Quindi un singleton dovrebbe svanire solo se l'intero processo lascia la memoria e in tal caso anche la classe dell'applicazione lascerà la memoria, ma chiamerà i metodi onDestroy dell'Applicazione e ciò ti permetterà di chiudere in sicurezza il tuo DataManager e mantenere i dati importanti in memoria.

Detto ciò alle tue due varianti.

La via per Android sarebbe rendere il DataManager uno ContentProvider. Ciò consentirà l'accesso ai dati da ogni attività senza detenere un riferimento globale. Non sono sicuro di come si costruisce un Content Provider di memorizzazione nella cache che rimane nella memoria e non viene reintegrato troppo spesso.