56

Sto valutando i framework DI (Dependency Injection) per un'applicazione Android. I migliori contendenti sono: Dagger (con Butter Knife) e Android Annotations. Capisco che Dagger e ButterKnife provengono dalla stessa fonte e si completano a vicenda. Here're sono le matrici fondamentali che io sto cercando:Coltello Dagger and Butter contro annotazioni Android

  1. Facilità d'uso (la nostra generazione è basata su Gradle e usiamo Android Studio IDE)
  2. supporto Testing (usiamo Robotium per i test funzionali e RoboLectric per unit testing)
  3. performance (quadri dI usano riflessione, che uno è più veloce?)
+4

Google chiede espressamente di non utilizzare l'iniezione di dipendenza https://developer.android.com/training/articles/memory.html#Android –

+7

@IllegalArgument che puntano solo dice "quei quadri tendono a fare un sacco di processo di inizializzazione per la scansione annotazioni". Dagger e AndroidAnnotations (probabilmente anche Butter Knife come sostiene, ma non ne sono sicuro) fanno tutti la loro magia in fase di compilazione che potrebbe non essere applicabile. – kizzx2

+0

Vedere http://www.reddit.com/r/androiddev/comments/28vlrt/dagger_and_butter_knife_vs_android_annotations/ – ChrLipp

risposta

5

Google non chiede espressamente di non utilizzare l'iniezione di dipendenza. Ma leggendo la richiesta ci si accinge a parlare di più della libreria DI basata su guise/reflection. cose come l'annotazione Android non usano riflessioni e compilano completamente il codice generato dal tempo, mentre il coltello da burro e il pugnale usano una piccola quantità di riflesso ottimizzata per Android. ma è presumibilmente leggermente più potente dell'annotazione Android. Dipende davvero dal progetto e da quanto colpo di prestazioni sei disposto a prendere. a mio avviso, usare solo il coltello per il burro è sufficiente per accelerare lo sviluppo del codice da solo. se hai bisogno di un po 'più di uso annotazione Android. e infine se la tua volontà di fare una leggera performance colpita a causa della riflessione, l'opzione migliore senza assolutamente distruggere le prestazioni con una riflessione basata sul guice powerhouse è il pugnale + coltello per il burro.

+7

Google sta sviluppando congiuntamente dagger2: http://google.github.io/dagger/ –

+1

Hanno fatto il loro , ecco perché: https://developer.android.com/tools/data-binding/guide.html https://www.youtube.com/watch?v=5sCQjeGoE7M –

49

AndroidAnnotations
utilizza la compilazione di elaborazione di annotazione tempo. Genera una sottoclasse con un carattere di sottolineatura apppended al nome originale (MyActivity_ generato da MyActivity). Quindi per farlo funzionare devi sempre usare la classe generata per i riferimenti invece della tua classe originale.

Ha un set di funzioni molto ricco, vedere list of available annotations.

Butterknife
utilizza anche compilazione elaborazione di annotazione tempo, ma genera classi finder che vengono utilizzati da una classe centrale(). Ciò significa che è possibile utilizzare la classe originale per il riferimento, ma è necessario chiamare l'iniezione manualmente. Una copia dall'introduzione butterknife:

@Override public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.simple_activity); 
    ButterKnife.inject(this); 
    // TODO Use "injected" views... 
} 

Il set di funzionalità non è così ricca, butterknife supporta vista iniezione (AndroidAnnotations equivalente sarebbe @ViewById e @ViewsById) e qualche evento vincolante (per un elenco completo consultare la directory namespace here, conta le annotazioni degli eventi).

Dagger
è un'implementazione DI per Android, simile a Guice. Utilizza inoltre l'elaborazione dell'annotazione del tempo di compilazione e genera grafici di oggetti che si utilizzano per l'iniezione manuale. È possibile distinguere tra il grafico dell'oggetto dell'applicazione e i grafici dell'oggetto con scope per l'iniezione, ad es. nelle attività. Qui sotto potete vedere un esempio Application.onCreate:

@Override public void onCreate() { 
    super.onCreate(); 
    objectGraph = ObjectGraph.create(getModules().toArray()); 
    objectGraph.inject(this); 
    // use injected classes 
} 

ho trovato è più difficile da iniziare con il pugnale, ma questo potrebbe essere solo la mia esperienza.Tuttavia vedere alcuni video qui per un inizio migliore: 1, 2

Dal set di funzionalità punto di vista direi che Dagger implementa funzionalità che potrebbero essere comparati a funzionalità @EBean e @Bean di AndroidAnnotation.

Sommario
Se si sta confrontando la facilità d'uso, testare il supporto e le prestazioni non trovo molta differenza tra l'utilizzo di AndroidAnnotation e butterknife + Dagger. Le differenze sono nel modello di programmazione (utilizzare le classi con _ invece di utilizzare quelle originali e chiamare l'iniezione manualmente) e nel set di funzionalità.

AndroidAnnotation offre un elenco completo di funzionalità, ma vi collega a determinate librerie. Ad esempio, se si utilizza la sua API di riposo, è necessario utilizzare Spring Android. Hai anche annotazioni per funzioni come OrmLite (@OrmLiteDao) indipendentemente se usi OrmLite o no.

Alla fine è una questione di gusti, almeno secondo me.

+0

Penso che tu abbia fatto un errore su ButterKnife: usa compila tempo Annotation (RetentionPolicy.CLASS), ma inserisce il codice in fase di runtime, con conseguente maggiore dispendio di tempo. – ech0s7r

+3

Penso che tutte le soluzioni producano codice durante il tempo di compilazione e questo codice viene chiamato (in fase di esecuzione) per eseguire l'iniezione. Ad esempio, in Annotazioni Android genera una sottoclasse ('MyActivity_') che esegue l'iniezione per' MyActivity'. In Butterknife devi chiamare 'ButterKnife.inject (this) 'che delega al codice generato. – ChrLipp

+0

Nessun amore per la libreria di collegamento dati di Android? https://developer.android.com/tools/data-binding/guide.html Finirai per dimenticare tutto questo. –

19

Ecco l'articolo di Nizza in Dzone blog.

Abbiamo ad avere bisogno di confrontare le caratteristiche di ciascuna, come ad esempio:

  • Vasi minimo richiesto
  • compatibilità ActionBarSherlock
  • iniezione per gli ascoltatori click
  • iniezione POJO
  • prestazioni

enter image description here

Solo Pojo iniezione manca in butterknife! Quindi sembra che Butterknife sia il vincitore!

Source

+1

Un'altra riga che vorrei aggiungere a questo grafico è "Supporto per progetti di libreria" che Butterknife non supporta, ma AndroidAnnotations fa tramite l'attributo resName (vedere https://github.com/excilys/androidannotations/wiki/Library-projects) . Questo è stato un affare per me usando Butterknife. –

+0

-1: la domanda non riguardava [RoboGuice] (https://github.com/roboguice/roboguice) (che è comunque ritirato e non più mantenuto), ma su [AndroidAnnotations] (http://androidannotations.org – TmTron

0

penso che il migliore tra i (in termini di prestazioni) butterknife e AndroidAnnotation è il secondo. ButterKnife utilizza l'annotazione in compilazione Annotation (RetentionPolicy.CLASS), ma inietta il codice in fase di runtime, con conseguente maggiore dispendio di tempo. Invece, AndroidAnnotations, elabora tutte le annotazioni in fase di compilazione.

+3

"ButterKnife inserisce codice in fase di esecuzione" - Sei sicuro? – naXa

+0

Leggi il primo paragrafo di questo articolo http://www.thekeyconsultant.com/2013/09/5-reasons-you-should-use-butterknife.html – Redman

1

Il reddit-thread citato da @ChrLipp ha qualcuno che usato tutti e tre sullo stesso progetto, parla molto di pugnale + butterknife ma dà anche AndroidAnnotations suo posto:

Per l'iniezione di dipendenza, butterknife viene utilizzato per Views, Dagger è utilizzato per tutti gli oggetti ed è altamente raccomandato e Annotazioni Android crea più di un framework per lo sviluppo di Android invece di iniettando oggetti nelle classi in modo che ciascuna libreria sia piuttosto uguale a l'una dall'altra. Dagger è equivalente a Guice ma è molto più veloce . Dagger è più potente delle annotazioni ButterKnife e Android in quanto inietta tutti gli oggetti anziché ButterKnife e Annotazioni Android che iniettano solo un determinato insieme di oggetti.

Dagger può essere un problema da configurare e configurare, ma ne vale la pena una volta effettuato il . Ma poi di nuovo, perché questi sono tutti abbastanza diversi tra loro, tutto dipende da quali sono le tue esigenze per il progetto.

Inoltre, parlando di ognuno di essere molto diverso, nel progetto si possibile utilizzare butterknife, Android annotazioni e Dagger tutti nello stesso progetto se si vuole veramente. Ognuno di loro ha la stessa idea, ma fa qualcosa di diverso da così da poterli usare tutti.

3

Utilizzare Annotazioni Android o Butterknife per facilitare la codifica. Ma non andare per Roboguice! Roboguice forza le tue attività, i frammenti si estendono alle classi di roboguzia. Non è divertente, affatto!

+0

Qual è il problema nell'estensione da RoboActivity (che si estende dall'attività) mentre tu può estendersi dall'attività? non stai perdendo nulla qui. – vijay

5

si dovrebbe dare una prova a Toothpick.

stuzzicadenti (il README):

  • puro java
  • veloce, non utilizza la riflessione ma l'elaborazione annotazione
  • semplice, flessibile ed estensibile & potente, robusto & testato
  • thread safe
  • documentato & Open Source
  • portata sicuro: impone perdite applicazioni gratis
  • prova orientato: si fa test facile
  • funziona molto bene con Android o qualsiasi altro quadro in base al contesto (come i contenitori web)

può anche essere più veloce di Dagger 2 nella maggior parte dei casi, ed è molto più semplice.

Nota: Sì, sono uno degli autori.

1

Perché preoccuparsi dell'iniezione di dipendenza?

Prima di andare oltre, si potrebbe anche chiedere: "Ma perché dovrei prendere in considerazione anche DI? La gente dice che il codice è più pulito, ma il mio codice non è mai disordinato. "Ora potrebbe essere vero quando ripensi a ciò che hai scritto pochi giorni fa per un progetto di hobby più piccolo in cui non fai nulla di complesso, salta i test unitari, e presto. Ma la realtà è diversa. Ci sono molte cose che si ottengono usando l'iniezione di dipendenza, alcune sono ovvie rispetto ad altre.

enter image description here See full comparison of All Android Dependency Injection libraries

Testabilità

Questo è probabilmente il più importante dal mio punto di vista. Ogni volta che scrivi dei test unitari (e dovresti sempre scriverli) devi assicurarti di testare il tuo codice e solo per la classe in questione. Non si vuole dipendere dalla logica di alcune librerie o di un'altra classe che viene testata separatamente. Come fai a fare questo? Il modo migliore sarebbe usare i mock che sono stati iniettati invece delle reali implementazioni. Dopo tutto, non vuoi che il test di una classe che parla a un servizio di terze parti esterno dipenda dalla connettività Internet e dalle tue credenziali reali per le quali ti viene addebitato.

Codice e responsabilità di separazione

Sulla base di quello che ho detto sui test, diventa chiaro che la separazione del codice avverrà naturalmente. Questo ti permetterà di dividere il codice in blocchi più piccoli che sono responsabili di una cosa alla volta. Piccole parti del codice portano alla pulizia, la pulizia porta alla leggibilità, la leggibilità porta a un minor numero di bug. E con tutto questo aumentiamo la manutenibilità del nostro codice.

Sostituibilità e l'adattamento

refactoring è una parte naturale di qualsiasi progetto di sviluppo. Svilupperemo il codice che deve essere modificato in futuro o addirittura sostituire completamente alcune implementazioni. Meno dobbiamo fare per raggiungerlo - meglio è. Con l'aiuto di Dependency Injection puoi adattare più facilmente il tuo codice, introdurre nuove dipendenze o addirittura modificarle completamente.