2009-11-07 12 views
8

Questa è una domanda che ho ricevuto per alcune app diverse che ho creato e che non ho ancora soddisfatto con nessuna delle soluzioni che ho trovato. Pensavo di metterlo fuori alla comunità per vedere altre soluzioni che potrebbero esserci.Buone alternative per condividere un complesso albero di oggetti tra le attività in Android?

Supponiamo che tu abbia un'attività che scarica un complesso albero di dati (in questo caso tramite json, ma potrebbe essere qualsiasi cosa), unmarshalls quei dati a un insieme di oggetti java (in questo caso usando gson, ma ancora, potrebbe essere qualsiasi cosa), quindi genera attività aggiuntive per visualizzare diverse parti di tali dati. Potrebbe esserci un'attività per visualizzare i viaggi nella tua risposta e un'altra per visualizzare i voli in quei viaggi e forse un'altra per visualizzare i passeggeri di quei voli.

La mia implementazione iniziale di questa app era quella di eliminare unmarshall tutti i Trip nella prima attività, quindi passarli per valore (come extra nell'intento) a TripActivity. TripActivity trasferisce quindi singoli voli a FlightActivity e così via.

Il problema con questo è che c'è una pausa notevole tra le attività mentre l'app serializza e deserializza i dati. Parliamo diversi secondi. La pausa è abbastanza evidente quando il mio albero usa Serialization o Parcelable per passare i dati in giro. I test iniziali delle prestazioni con l'utilizzo di Parcelable di google mostrano invece un aumento del 30% rispetto alla serializzazione, ma Parcelable è difficile da lavorare e non sembra gestire i riferimenti agli oggetti circolari come fa la serializzazione, e inoltre si ferma per quasi tutti i secondi, quindi ho messo quell'esperimento sul backburner mentre provavo altre cose.

Quindi ho provato a spostare l'albero degli oggetti direttamente nella classe Application. Ogni attività riceve l'albero direttamente dall'app ogni volta che ne ha bisogno. Ciò rende le prestazioni abbastanza veloci, ma gestire casi d'angolo come l'avvio/arresto di attività inattese (a causa di arresti anomali delle attività o perché l'attività è stata temporaneamente chiusa per rendere disponibile più memoria o qualsiasi altra causa) sembra difficile. Forse non è altro che implementare onSaveInstanceState(), non sono sicuro, ma la soluzione sembra un po 'hacky quindi non ho ancora approfondito l'analisi.

Quindi, alla ricerca di una soluzione meno complicata, ho provato a creare un ContentProvider personalizzato per archiviare e recuperare i miei oggetti. Poiché ContentProvider può essere configurato per l'esecuzione in-process utilizzando multiprocess=true, ho pensato che sarebbe un modo eccellente per evitare i costi di serializzazione mentre si eseguiva qualcosa di "standard" piuttosto che archiviare dati nell'oggetto Application. Tuttavia, ContentProvider non era chiaramente destinato a restituire tipi di oggetti arbitrari - supportano solo tipi come numeri, stringhe, booleani, ecc. Sembra che io possa finirne uno per archiviare oggetti arbitrari usando ContentResolver.getContentProviderClient().getLocalContentProvider() e accedendo direttamente alla mia classe personalizzata, ma io Non sono sicuro che sia meno hacky rispetto alla memorizzazione dei dati nell'oggetto Application.

Sicuramente qualcuno deve avere una buona soluzione a questo problema. Che cosa sto facendo di sbagliato?

risposta

3

Oltre alla soluzione di fiXedd, un altro è quello di utilizzare un servizio locale. Avere il servizio "proprietario" degli oggetti, con attività che chiamano le API del servizio per ottenere tutto ciò di cui ha bisogno. Il servizio può anche essere responsabile del recupero e dell'analisi dei dati, incapsulando quel bit di logica.

L'oggetto Application è il "passo-figlio dalla testa rossa" dei componenti Android.I membri del nucleo del team Android sono venuti contro la pratica della creazione di sottoclassi personalizzate Application, sebbene sia certamente supportato dall'API. Avendo progettato un'applicazione ADC2 200 che utilizzava una sottoclasse personalizzata Application, posso dire che avrei dovuto utilizzare anche un servizio nel mio caso. Vivi e impara ...

Utilizzando il modello di associazione locale, il servizio verrà automaticamente creato e distrutto in base alle esigenze, quindi non devi preoccuparti di questo. E, per definizione, un servizio locale viene eseguito nello stesso processo/VM delle tue attività, quindi non devi preoccuparti di eseguire il marshalling in eccesso come nello scenario ContentProvider.

+0

Sì, penso di essere su una barca simile. Iniziato facendo tutto in applicazione, e ora un servizio sembra la strada giusta da percorrere. Indagherò su refactoring ad un certo punto. Grazie per il consiglio! – emmby

+0

Preferisco anche il servizio. Cosa intendi con "proprio"? Salvate i dati su un oggetto statico nel servizio? Solitamente un servizio analizza i dati e quindi li invia in una trasmissione, quindi nel gestore dell'interfaccia utente viene utilizzato un gestore per visualizzare i dati o qualsiasi altra cosa. Ma se chiamo di nuovo il servizio, da dove viene il servizio a recuperare di nuovo quei dati? Questi dati vengono salvati su un oggetto statico nel servizio? Non vogliamo analizzare di nuovo il JSON .. –

1

Il modo in cui sto gestendo questo in una delle mie app è il download dei dati, quindi lo spingo in un database. In questo modo non devo portare tutti quegli oggetti intorno (che, IIRC, mangio circa 1kb ciascuno solo per l'istanziazione dell'oggetto) e posso facilmente recuperare solo i dati di cui ho bisogno. Non so se questo funzionerà per te, ma ha funzionato per il mio caso d'uso.

+0

Abbiamo provato questo al mio attuale lavoro, ma l'app ha continuato a bloccarsi e/o bloccarsi quando abbiamo provato a leggere o memorizzare i dati nel database. Sto cercando di stare lontano dai database SQLite d'ora in poi ... –

0

Un altro approccio sarebbe quello di salvare gli oggetti dati in un file di preferenze condivise. È così che abbiamo implementato una delle nostre app, ma questo approccio non mi è piaciuto perché sembra troppo lento.

È una cattiva pratica di codifica, ma il modo più veloce può essere utilizzare semplicemente un servizio per analizzare i dati e salvare i dati in una classe statica che è possibile utilizzare per il resto della vita dell'app.

Problemi correlati