2017-12-22 26 views
0

Ich versuche, dagger2 in meinem Projekt zu implementieren, aber ich bin mit einem Fehler konfrontiert "android .app.Application kann nicht ohne einen @Inject-Konstruktor oder eine @Announcated-Methode bereitgestellt werden. "dagger2 error "android.app.Application kann nicht ohne @Inject-Konstruktor oder von einer @ Provide-Annotated-Methode"

Hier ist mein Code:

App.java

package com.poppmedia.wallpaperautomaton; 

import android.app.Application; 

import com.poppmedia.wallpaperautomaton.di.DaggerAppComponent; 

import dagger.android.AndroidInjector; 
import dagger.android.DaggerApplication; 

/** 
* The Android {@link Application}. 
*/ 
public class App extends DaggerApplication { 
    @Override 
    protected AndroidInjector<? extends DaggerApplication> applicationInjector() { 
     return DaggerAppComponent.builder().create(this); 
    } 
} 

di/AppModule.java

package com.poppmedia.wallpaperautomaton.di; 

import android.app.Application; 
import android.content.Context; 

import javax.inject.Singleton; 

import dagger.Binds; 
import dagger.Module; 

/** 
* Provider application-wide dependencies. 
*/ 
@Module 
public interface AppModule { 
    @Binds 
    @Singleton 
    Context bindContext(Application application); 
} 

di/AppComponent.java

package com.poppmedia.wallpaperautomaton.di; 

import com.poppmedia.wallpaperautomaton.App; 

import javax.inject.Singleton; 

import dagger.Component; 
import dagger.android.AndroidInjector; 
import dagger.android.support.AndroidSupportInjectionModule; 

/** 
* Injects application dependencies. 
*/ 
@Singleton 
@Component(modules = { 
     AndroidSupportInjectionModule.class, 
     AppModule.class, 
}) 
public interface AppComponent extends AndroidInjector<App> { 
    @Component.Builder 
    abstract class Builder extends AndroidInjector.Builder<App> {} 
} 

di/TestClassModule.java

package com.poppmedia.wallpaperautomaton.di; 

import android.content.Context; 

import com.poppmedia.wallpaperautomaton.TestClass; 

import javax.inject.Singleton; 

import dagger.Module; 
import dagger.Provides; 

@Module 
public class TestClassModule { 
    @Provides 
    @Singleton 
    TestClass provideTestClass(Context context) { 
     return new TestClass(context); 
    } 
} 

di/TestClassComponent.java

package com.poppmedia.wallpaperautomaton.di; 

import com.poppmedia.wallpaperautomaton.TestClass; 

import javax.inject.Singleton; 

import dagger.Component; 

@Singleton 
@Component(modules = { AppModule.class, TestClassModule.class }) 
public interface TestClassComponent { 
    TestClass getTestClass(); 
} 

TestClass.java

package com.poppmedia.wallpaperautomaton; 

import android.content.Context; 

import javax.inject.Inject; 
import javax.inject.Singleton; 

@Singleton 
public class TestClass { 
    private Context mContext; 

    @Inject 
    public TestClass(Context context) { 
     mContext = context; 
    } 
} 

Danke.

+1

Ich sehe weder Sie binden Ihre 'Anwendung' in einem Komponentenerstellungsprogramm, noch fügen Sie es zu einem Modul hinzu und stellen es dort zur Verfügung. –

+0

versuchte ich folgendes hinzufügen: ** di/AppModule.java ** '@Binds @Singleton Anwendung bindApplication (Application Anwendung);' ** di/AppComponent.java ** 'Anwendung GetApplication (); ' Und ich bekomme einen Abhängigkeitszyklusfehler. –

+0

@DanielGorgan Probieren Sie es mit '@Binds Application bindApplication (App-App);' so dass Sie das allgemeine 'Application'-Objekt an Ihre benutzerdefinierte Implementierung binden, die Sie 'App' aufrufen. Du kannst das '@ Singleton' nehmen oder verlassen, aber ich lasse es weg - es hilft dir hier nicht. –

Antwort

0

In Ihrem speziellen Fall, Sie verpassen:

@Binds Application bindApplication(App app); 

Dies ist wichtig, weil dagger.android wird automatisch eine Bindung an die spezifische Anwendung, Aktivität umfasst, Fragment, Dienstleistung, BroadcastReceiver, etc Unterklasse aber nicht die allgemeine Objekt. (Sie würden der Lage sein App zu injizieren, aber nicht Anwendung und YourActivity aber nicht Aktivität.) Wenn Sie auf dagger.android angeben möchten, dass er Anforderungen für Anwendungs ​​erfüllen sollte Ihre App-Instanz verwenden, können Sie muss eine Bindung wie oben enthalten.

Im Allgemeinen ist dies eine ziemlich sichere Sache für Application, Activity, Service und BroadcastReceiver, aber nicht Fragment (nativ oder in den Compat-Bibliotheken); Dies liegt daran, dass dagger.android verschachtelte Fragmente respektiert, und in diesem Fall wäre es zweideutig, welches Fragment injiziert werden soll.

Obwohl Sie die Anwendung durch ein Modul und Instanzfeld wie in luffy's answer zur Verfügung stellen kann, das ist mehr vorformulierten, als Sie brauchen, und ist auch weniger optimiert: Dagger Code schreiben, wird Ihre @Provides Methode aufzurufen, während Sie deklarativ Dagger sagen kann, Um eine bestehende Bindung wiederzuverwenden, verwenden Sie @Binds oder schreiben Sie eine static @Provides Methode, die vermeidet, den Aufruf einer Instanz aufzurufen.

Siehe the Dagger advantages of @Binds und the Android advantages of static dispatch.

-1

In AppModule, @Binds eine Anwendung, aber Anwendung wird von keinem anderen Modul zur Verfügung gestellt.

Da die Anwendung von Android Framework erstellt wird, sollten Sie AppModule die Anwendung von außen bereitstellen lassen.

@Module 
public class AppModule { 
    private Application mApp; 
    public AppModule(Application app) { 
     mApp = app 
    } 
    @Singleton 
    Context provideContext() { 
     return mApp 
    } 
} 
+0

Dies ist nicht der beste Weg, um es zu tun: Es gibt bereits eine Bindung für 'App', und für einfache Bindungen wie diese ist es vorzuziehen,' @ Binds' oder '@BindsInstance' zu ​​verwenden. –

Verwandte Themen