dagger2错误“没有@Inject构造函数或来自@ Provide-annotated方法,不能提供android.app.Application”

时间:2017-12-22 10:46:10

标签: java android dagger-2

我正在尝试在我的项目中实现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);
    }
}

的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;
    }
}

谢谢。

2 个答案:

答案 0 :(得分:2)

在您的具体情况下,您将失踪:

@Binds Application bindApplication(App app);

这很重要,因为dagger.android会自动包含对特定应用程序,活动,片段,服务,BroadcastReceiver等子类的绑定,而不包括通用对象。 (您可以注入 App 但不能应用 YourActivity ,但不能注入活动。)如果你想向dagger.android表明它应该使用你的App实例满足对Application的请求,你必须包含一个绑定,如上所述。

一般来说,对于Application,Activity,Service和BroadcastReceiver来说这是非常安全的事情,但不是Fragment(本机或compat库);这是因为dagger.android尊重嵌套的片段,在这种情况下,片段注入将是不明确的。

虽然您可以通过模块和实例字段提供应用程序,如luffy's answer中所示,但这比您需要的更多样板,并且也不太优化:Dagger将编写代码来调用您的@Provides方法,您可以声明性地告诉Dagger使用@Binds重用现有绑定,或者编写一个static @Provides方法,以避免在实例上调用该调用。

请参阅the Dagger advantages of @Bindsthe Android advantages of static dispatch

答案 1 :(得分:-1)

在AppModule中,@绑定应用程序,但任何其他模块都不提供应用程序。

因为应用程序是由Android框架创建的,所以应该让AppModule从外部提供应用程序。

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