2015-02-25 9 views
8

Per rendere le cose semplici, supponiamo che io voglio per iniettare EmailValidator da validatori Apache nella mia attività:Dagger2 - nulla invece che iniettata oggetto

public class MainActivity extends FragmentActivity { 

    @Inject 
    EmailValidator emailValidator; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
    } 

Ho una classe MainModule:

@Module 
public class MainModule { 

    @Provides 
    public EmailValidator providesEmailValidator() { 
     return EmailValidator.getInstance(); 
    } 
} 

e MainComponent interfaccia:

@Singleton 
@Component(modules = MainModule.class) 
public interface MainComponent { 

    EmailValidator getEmailValidator(); 
} 

Quando si tenta di utilizzare il mio validatore in attività, sto diventando un nullpoi nter eccezione:

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean org.apache.commons.validator.routines.EmailValidator.isValid(java.lang.String)' on a null object reference 

Ovviamente mi manca qualcosa. So che il pugnale crea per me l'implementazione dei componenti. Dovrei usarlo? Come?

Se faccio la seguente nel mio metodo onCreate:

 emailValidator = Dagger_MainComponent.create().getEmailValidator(); 

poi tutto funziona bene.

Tuttavia, desidero essere in grado di utilizzare l'annotazione @Inject ovunque (probabilmente su setter/costruttore anziché su un campo).

Cosa mi manca?

Ho fatto qualcosa di simile a dagger1 e ha funzionato. Ovviamente dovevo chiamare lo ObjecGraph.inject(this) in attività. Qual è l'equivalente di dagger2?

EDIT:

Ok, così ho trovato una soluzione. Se qualcuno avrà mai un problema, ci sono alcuni frammenti:

1) ho creato una classe di applicazione:

public class EmailSenderApplication extends Application { 

    private MainComponent component; 

    @Override 
    public void onCreate() { 
     super.onCreate(); 

     component = Dagger_MainComponent 
       .create(); 

     component.inject(this); 
    } 

    public MainComponent component() { 
     return component; 
    } 
} 

2) In AndroidManifest.xml:

<application 
     android:name=".EmailSenderApplication" 
     ... 

3) E infine, nella classe di attività in cui voglio iniettare alcune componenti quelle due brutte linee infernali:

component = ((EmailSenderApplication) getApplication()).component(); 
component.inject(this); 
+0

Non riesco a chiamare 'inject' sul mio componente. Anche la sintassi di Dagger_MainComponent sembra essere stata modificata in DaggerMainComponent. –

risposta

9

Sguardi come è necessario costruire il componente come in:

component = Dagger_ MainComponent.builder() 
     .mainModule(new MainModule()) 
     .build(); 

In genere, si esegue questa operazione nel metodo della vostra applicazione, in this fashiononCreate.

Una buona risorsa che può essere d'aiuto è la example apps in the Dagger 2 repo.

Ho anche trovato utile questo PR, da un suggested update to Jake Wharton's u2020 sample app (dal principale Dagger 2 Engineer). Fornisce una buona panoramica delle modifiche da apportare quando si passa da Dagger 1 a 2 e, apparentemente, è ciò che è he points people to as well.

+0

Già provato, ottenendo ancora un'eccezione. – slnowak

+0

L'ho capito. A causa di link utili, sto accettando questa risposta :) – slnowak

+0

Contento di averlo risolto! Dalle tue modifiche sopra, sembra che tu abbia un caso in cui nessuno dei tuoi costruttori di moduli richiede argomenti del costruttore. Quando è vero, il componente avrà invece un metodo 'create' da utilizzare. È probabile che, dopo un po ', dovrai passare la tua applicazione in uno di questi moduli e quando ciò accadrà, dovrai ricorrere all'utilizzo del builder come descritto sopra. – gMale

Problemi correlati