我正在尝试在我的项目中实现dagger2,但是我遇到了一个错误“如果没有@Inject构造函数或者@Project-annotated方法,就无法提供android.app.Application”。
这是我的代码:
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);
}
}
of / 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);
}
中/ 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> {}
}
at / 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);
}
}
在/ 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();
}
test class.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;
}
}
谢谢。
在您的具体情况下,您错过了:
@Binds Application bindApplication(App app);
这很重要,因为dagger.android会自动包含对特定Application,Activity,Fragment,Service,BroadcastReceiver等子类的绑定,但不包括对常规对象的绑定。 (您可以注入App而不是Application,而不是YourActivity而不是Activity。)如果您想向dagger.android表明它应该使用您的App实例满足Application的请求,您必须包含如上所述的绑定。
一般来说,对于Application,Activity,Service和BroadcastReceiver来说,这是非常安全的事情,但不是片段(本机或compat库);这是因为dagger.android尊重嵌套片段,在这种情况下,片段注入将是不明确的。
虽然您可以通过luffy's answer中的模块和实例字段提供应用程序,但这比您需要的更多样板,并且也不太优化:Dagger将编写代码来调用您的@Provides
方法,而您可以声明性地告诉Dagger重用现有的使用@Binds
绑定或编写一个static @Provides
方法,避免在实例上调用调用。
见the Dagger advantages of @Binds
和the Android advantages of static dispatch。
在AppModule中,@绑定应用程序,但任何其他模块都不提供应用程序。
由于Application是由Android框架创建的,因此您应该让AppModule从外部提供Application。
@Module
public class AppModule {
private Application mApp;
public AppModule(Application app) {
mApp = app
}
@Singleton
Context provideContext() {
return mApp
}
}