19

Nel tipico progetto Android in cui abbiamo bisogno di estrarre dati da qualche parte (REST, SQL, cache, ecc.) Nell'interfaccia utente in modo pulito usiamo comunemente un caricatore, servizio o (possibilmente, yuk) un AsyncTask, ma trovo tutto questi approcci non soddisfacenti per diversi motivi:Perché non dovrei utilizzare un bus di messaggi al posto di caricatori e servizi?

  • Sono brutti, soprattutto Pale che hanno una struttura API spaventosa
  • e 'troppo facile da ottenere avvolto in fili, e battistrada sul thread UI
  • la nostra presentazione il codice di livello viene inquinato con codice Android e boilerplate. Passiamo spesso oggetti Android (es. Cursori) direttamente al livello dell'interfaccia utente, il che rende quasi impossibile realizzare un'architettura pulita. Questo ci obbliga a combinare codice specifico del dominio aziendale (idealmente semplici oggetti Java) con il codice della piattaforma Android - non eccezionale per leggibilità, manutenzione, test o flessibilità per lo sviluppo futuro. In pratica spesso riceviamo classi di attività/frammenti enormi e disordinati.

Sono attratto da idee come quelle descritte in questi articoli: http://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/ http://antonioleiva.com/mvp-android/ http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html

Avere successo iniziato a utilizzare MVP per rompere le Attività/Frammenti/Vista in pezzi più piccoli/più puliti, ho Ora penso che una soluzione ai problemi di cui sopra potrebbe essere quella di affidarsi a un bus di messaggi (Otto, EventBus, ecc.) anziché a servizi o caricatori o qualsiasi altra cosa per interagire con i dati del dominio.

Quindi in pratica ciò significherebbe invece di utilizzare (ad esempio) un CursorLoader per caricare un cursore dal database, preferirei invece utilizzare il bus dei messaggi per inviare un messaggio per richiedere dati, i dati vengono caricati su uno sfondo thread in risposta a tale messaggio e quindi gestire i dati di risposta quando arriva tramite un messaggio sul thread dell'interfaccia utente. Fondamentalmente per me preferirei che la struttura dei dati fosse esclusa dal dominio aziendale, non dal dominio Android, quindi preferirei una serie di oggetti di business a un Cursore.

Questa fase dell'ingegneria comporta sempre compromessi e, sebbene ciò sembri fornire una separazione molto più netta delle preoccupazioni, c'è meno caricatore per il caricatore/servizio, quali sono gli aspetti negativi?

  • Può essere più difficile (soprattutto per i nuovi sviluppatori) per capire il codice
  • Sarà necessario garantire i messaggi vengono inviati e ricevuti sui fili giusti (Otto sembra simili possono avere limitazioni qui)
  • Sarà necessario evitare la tentazione di implementare tutto come un messaggio, che alla fine sarebbe controproducente
  • Il passaggio di raccolte di oggetti business in giro potrebbe risultare meno efficiente rispetto all'utilizzo di oggetti come Cursori. Anche se in molti scenari è un problema nella pratica?
  • Non so se Otto/EventBus sono progettati solo per passare messaggi molto piccoli, o se è opportuno passare oggetti più grandi (ad esempio una serie di oggetti di business).

La mia domanda è ci sono motivi fondamentali per NON adottare questo approccio basato su messaggi con le app Android?

risposta

1
+2

Il primo articolo dice: "Così se le tue astrazioni non forniscono un beneficio significativo, dovresti evitarle "quindi più di un avvertimento per stare attento che una regola contro di esso. Il secondo (DI) sembra un po 'obsoleto in quanto i personaggi di Dagger sono molto più efficienti. L'ultimo sembra decisamente uno svantaggio di questo approccio, ma a meno che il set di dati non sia grande o il codice chiamato regolarmente (ad esempio un adattatore) sia sufficiente per eliminare i vantaggi di un codice più pulito? Non sono così sicuro... –

1

eventuali ragioni fondamentali di non prendere questo approccio basata su messaggi con Android apps

Non c'è, immagino. Nella mia pratica ho lavorato con materiale di "stock" come Loader e AsyncTasks (non metterei i servizi in questa riga, perché la sua responsabilità è molto più ampia). Quindi la cosa del bus è stata implementata e indovina cosa? La vita è diventata più facile e più prevedibile, il disaccoppiamento è aumentato. Una volta che mi sono trasferito completamente a Rx, il lavoro è diventato non solo più facile, ma più divertente! Tuttavia, nulla ti salverà dall'affrontare i cicli di vita.

Tutto questo è solo dettagli di implementazione, è più importante mantenere le cose globali chiare. Quando parli di Architettura pulita, il problema è nasconderlo dal livello dell'interfaccia utente (Attività, Frammenti, Viste ...) come e dove vengono gli oggetti. Una volta incapsulato questo specifico lavoro in casi d'uso, non è un grosso problema quale strumento usare: caricatori, bus o Rx - il tuo livello UI dovrebbe limitarsi all'interfaccia fornita da usecase - callback, eventi o osservabili

I'd punto due cose:

  1. Quanto meno qualsiasi livello conosce l'implementazione del caso, tanto meglio.
  2. Se hai scelto uno strumento particolare per l'implementazione, usalo ovunque. Non mescolare più strumenti per lo stesso lavoro.
0

Alcuni anni fa non c'erano dispositivi Android potenti con 3 GB di RAM o più. Quando hai una chiamata di rete dalla tua app e la tua app si interrompe, ad esempio ricevi una telefonata e mandi la tua app sullo sfondo (se non usi un servizio) la tua app viene uccisa e tu sprechi la tua chiamata di rete. Se hai un servizio in esecuzione associato alla tua applicazione, la tua app avrà una priorità bassa per essere uccisa dal sistema operativo Android

Inoltre con i servizi puoi rendere i tuoi lavori non-ui o i processi di lunga durata separati da ui-thread. È un buon approccio per l'app ui non-blocking. Inoltre puoi gestire i cambiamenti di orientamento.

Oggi come dici tu ci sono alcune altre opzioni (librerie, modelli, ecc.) In Android Dev. mondo come MVP, MVC, MVVM, Retrofit, OttoBus ...

Penso che non ci sia un certo modo corretto per sviluppare la tua app Android come "devi usare MVP, Retrofit, servizi, caricatori, MVVM, Dati Legame ecc. "

Mentre si sta sviluppando un'app per Android è possibile considerare questi principi e si possono fare le scelte di modello e libreria in base a questi principi.(L'ordine dei principi può essere cambiato secondo il progetto, tempo, risorse, ecc ..)

1- Clean code 
2- Seperate layers 
3- Non Blocking Ui 
4- Don't waste user's resources. (Avoid unneccassry network calls, memory allocation etc.) 
5- Support orientation change. 
6- Testing 
7- Clean Ui Design (Material Design) 

Questo è un vecchio video, ma ogni Sviluppatore Android dovrebbe guardarlo: https://www.youtube.com/watch?v=xHXn3Kg2IQE

Problemi correlati